springboot 使用 Spring Data Elasticsearch 高级查询文档

上接:springboot 使用 Spring Data Elasticsearch 操作 Elasticsearch 7.9-创建工程

查询操作

service类

package day1.service;

import day1.entity.Toutiao;
import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.query.functionscore.FieldValueFactorFunctionBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

@Service
public class ESToutiaoSearchSrvImpl {
    @Autowired
    private ElasticsearchRestTemplate temp;
    /**
     * 短语查询
     *
     * @return
     */
    public SearchHits<Toutiao> matchPhraseQuery(String keyword) {
        //1.查询title中含有 keyword 的内容的记录
        MatchPhraseQueryBuilder builder = QueryBuilders.matchPhraseQuery("title", keyword);
        //2.构建查询
        NativeSearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(builder)
                .build();
        //3.执行查询
        SearchHits<Toutiao> shs = temp.search(query,Toutiao.class);
        return shs;
    }
    /**
     * 通配符查询,使用keyword类型,区分大小写。按照like排序,且分页
     *
     * @return
     */
    public SearchHits<Toutiao> wildcardQuery(String keyword, Integer pageNum, Integer pageSize){
        if(pageNum==null){
            pageNum=1;
        }
        // 关键字查询
        QueryBuilder wildcard=QueryBuilders.wildcardQuery("title.keyword",keyword);
        //设置查询分页,从第一页开始,一页显示10条,从0开始
        PageRequest page = PageRequest.of(pageNum, pageSize);
        //按照点赞数量降序排序
        SortBuilder sort=SortBuilders.fieldSort("like").order(SortOrder.DESC);

        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(wildcard)
                .withPageable(page)
                .withSort(sort)
                .build();
        SearchHits<Toutiao> shs=temp.search(nativeSearchQuery,Toutiao.class);
        return shs;
    }
    /**
     * 全文索引查询
     *
     * @return
     */
    public SearchHits<Toutiao> match(String text, Integer pageNum, Integer pageSize){
        //match查询
        QueryBuilder match=QueryBuilders.matchQuery("title",text);
        //设置查询分页,从第一页开始,一页显示10条,从0开始
        PageRequest page=PageRequest.of(pageNum,pageSize);
        //按照点赞数量降序排序
        SortBuilder sort=SortBuilders.fieldSort("like").order(SortOrder.DESC);
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(match)
                .withPageable(page)
                .withSort(sort)
                .build();
        SearchHits<Toutiao> shs=temp.search(query,Toutiao.class);
        return shs;
    }
    /**
     * bool 查询
     *
     * @return
     */
    public SearchHits<Toutiao> boolQuery(String title, String content, Integer pageNum, Integer pageSize) {
        //1.创建QueryBuilder(即设置查询条件)这儿创建的是组合查询(也叫多条件查询),后面会介绍更多的查询方法
        /*组合查询BoolQueryBuilder
         * must(QueryBuilders)   :AND
         * mustNot(QueryBuilders):NOT
         * should:               :OR
         */
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //查询标题中必须有 入门,内容必须有 技巧
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("title",title));
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("content",content));
        //设置查询分页,从第一页开始,一页显示10条,从0开始
        PageRequest page = PageRequest.of(pageNum, pageSize);
        //按照点赞数量降序排序
        SortBuilder sort= SortBuilders.fieldSort("like").order(SortOrder.DESC);
        //2.构建查询
        NativeSearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(page)
                .withSort(sort)
                .build();
        //3.执行查询
        SearchHits<Toutiao> shs = temp.search(query,Toutiao.class);
        return shs;
    }
    /**
     * 范围查询
     *
     * @return
     */
    public SearchHits<Toutiao> range(String text, int from, int to, Integer pageNum, Integer pageSize){
        QueryBuilder match=QueryBuilders.matchQuery("content",text);

        QueryBuilder range=QueryBuilders.rangeQuery("like").gt(from).lte(to);

        BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
        boolQueryBuilder.must(match);
        boolQueryBuilder.filter(range);
        //设置查询分页,从第一页开始,一页显示10条,从0开始
        PageRequest page=PageRequest.of(pageNum,pageSize);
        //按照点赞数量降序排序
        SortBuilder sort=SortBuilders.fieldSort("like").order(SortOrder.DESC);
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(page)
                .withSort(sort)
                .build();
        SearchHits<Toutiao> shs=temp.search(query,Toutiao.class);
        return shs;
    }
    public double maxLike(){
        MaxAggregationBuilder max= AggregationBuilders
                .max("max_like")
                .field("like");
        PageRequest page=PageRequest.of(0,1);
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .addAggregation(max)
                .withPageable(page)
                .build();
        SearchHits<Toutiao> shs=temp.search(query,Toutiao.class);
        Aggregations aggregations = shs.getAggregations();
        ParsedMax agg=aggregations.get("max_like");
        double val=agg.getValue();
        return val;
    }
    /*
    二次评分
     */
    public SearchHits<Toutiao> functionScore(String text, Integer pageNum, Integer pageSize){
        MatchQueryBuilder mqb=QueryBuilders.matchQuery("title", text);
        FieldValueFactorFunctionBuilder fffb=ScoreFunctionBuilders
                .fieldValueFactorFunction("like")
                .modifier(FieldValueFactorFunction.Modifier.LOG1P);
        // 分数,并自动按分排序(对单个属性进行查询)
        FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.
                functionScoreQuery(mqb,fffb);

        PageRequest page=PageRequest.of(pageNum,pageSize);
        Query query = new NativeSearchQueryBuilder()
                .withQuery(functionScoreQueryBuilder)
                .withPageable(page)
                .build();
        SearchHits<Toutiao> shs = temp.search(query, Toutiao.class);
        return shs;
    }
}

测试类

package test;

import day1.Main;
import day1.entity.Toutiao;
import day1.service.ESToutiaoSearchSrvImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Main.class)
public class TestESToutiaoSearchSrvImpl {
    @Autowired
    private ESToutiaoSearchSrvImpl service;

    @Test
    public void matchPhraseQuery(){
        SearchHits<Toutiao> shs = service.matchPhraseQuery("mysql java");
        //4.获取总条数(用于前端分页)
        System.out.println("共:"+shs.getTotalHits()+" 条记录!");
        //5.获取查询到的数据内容(返回给前端)
        for (SearchHit<Toutiao> item : shs) {
            Toutiao toutiao=item.getContent();
            System.out.println(toutiao);
        }
    }
    @Test
    public void wildcardQuery(){
        // 查询 title是java 开头记录
        SearchHits<Toutiao> shs = service.wildcardQuery("java*", 0, 5);

        System.out.println("共:"+shs.getTotalHits()+" 条记录!");
        for(SearchHit<Toutiao> item : shs){
            Toutiao toutiao=item.getContent();
            System.out.println(toutiao);
        }
    }

    @Test
    public void match(){
        SearchHits<Toutiao> shs = service.match("java mysql",1,5);
        for(SearchHit<Toutiao> item : shs){
            Toutiao toutiao=item.getContent();
            System.out.println(toutiao);
        }
    }
    @Test
    public void boolQuery(){
        SearchHits<Toutiao> shs = service.boolQuery("入门", "技巧", 0, 5);

        //4.获取总条数(用于前端分页)
        System.out.println("共:"+shs.getTotalHits()+" 条记录!");
        //5.获取查询到的数据内容(返回给前端)
        for (SearchHit<Toutiao> item : shs) {
            Toutiao toutiao=item.getContent();
            System.out.println(toutiao);
        }
    }
    @Test
    public void range(){
        SearchHits<Toutiao> shs = service.range("java", 229, 983, 0, 5);

        //4.获取总条数(用于前端分页)
        System.out.println("共:"+shs.getTotalHits()+" 条记录!");
        for(SearchHit<Toutiao> item : shs){
            Toutiao toutiao=item.getContent();
            System.out.println(toutiao);
        }

    }

    @Test
    public void maxLike(){
        double val = service.maxLike();
        System.out.println(val);
    }
    @Test
    public void functionScore(){
        SearchHits<Toutiao> shs = service.functionScore("java", 0, 5);

        List<SearchHit<Toutiao>> list=shs.getSearchHits();
        for(SearchHit<Toutiao> item:list){
            Toutiao toutiao=item.getContent();
            System.out.println("score:"+item.getScore()+"--"+toutiao);
        }
    }
}

原文出处:/show_1IX1tOTe226Q.html