ElasticsearchTemplate 常用API

注:该文ElasticsearchTemplate基于spring date elasticsearch 2.3.2版本,4.X之后,ElasticsearchTemplate更新为ElasticsearchRestTemplate,并且query为前缀的方法已经被定义为过期方法。后续会找时间更新ElasticsearchRestTemplate

前言

ElasticsearchTemplateSpring对ES api的封装,提供大量的类完成各种查询。

一般使用SearchQuery或者NativeSearchQuery 做一些简单查询

源码分析

ElasticsearchTemplate 类中常用的查询方法,在 ElasticsearchTemplate 中,执行查询的大多都是 query 开头,而 query 方法,第一个参数是 Query 的实现类

在这里插入图片描述

可以很清楚的看到,实际查询中,调用的大多是Query的实现类,而经常使用的,是NativeSearchQuery ,下面使用NativeSearchQuery 一些常用API和注意事项,供人学习也作为笔记记录。

Query 源码分析

image-20200822105409526.png

看图解析
image-20200822114137445.png

果然,画图才是王道,Query 底下实现的类有 NativeSearchStringQueryCriteriaQuery,而我们经常使用的是NativeSearchQuery

接下来,再看NativeSearchQuery

在这里插入图片描述

源码中,NativeSearchQuery的构造方法中,参数是QueryBuilder

这个又是什么?

从名字分析,Query 查询,builder 构建,很清楚的分析出来,QueryBuilder 用来构建查询条件,过滤条件。就好比SQL语句后面where name = "张三" 跟这个是一个意思。

在这里插入图片描述

这里构建查询条件的很多种,常用的一般就几个,其他可以看ES的api使用文档,这里基本上跟那边对应

在这里插入图片描述

分析到这里基本上就差不多了,这里只是说简单使用Spring中提供了一个类QueryBuilders ,里面有很多方法来完成各种各样的QueryBuilder的构建,字符串型的,Boolean型的,match,Term等。

基本使用

单字符串全文查询

queryStringQuery 意思是,不用匹配指定的列名,全表匹配,比如 张三 这个名字,如果有经过分词,则会匹配 张,三,张三,这三种条件,如果没有分词,则只会匹配张三。(关于分词可以看这一篇),传送门

public List<User> getSearchByName(String name){
    // 构建分页
    Pageable page = new PageRequest(0,999);
    // 构建查询语句
    SearchQuery searchQuery = new
NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(name)).withPageable(pageable).build();
    return elasticsearchTemplate.queryForList(searchQuery,User.class);
}

注意:这里queryForList,源码里面实际是调用到了queryForPage,而queryForPage如果没有指定,默认查询是10条,如果想要查询全部,使用 elasticsearchTemplate.count(searchQuery); 先查询所有条数,再根据条数查询所有

指定字段模糊查询

matchQuery,指定字段模糊查询,跟mysql中的like类似,minimumShouldMatch可以用在match查询中,设置最少匹配了多少百分比的能查询出来。

public List<User> getMatch(String name){
    // 构建查询语句
    // .minimumShouldMatch("75%");
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("name", name)).withPageable(pageable).build();
    return elasticsearchTemplate.queryForList(searchQuery, User.class);
}

指定字段短语匹配

PhraseMatch 词语比较多的匹配,比如面试核心知识点,面试知识点不会被匹配出来,只会匹配一连贯的短语,如果输入知识点,会被匹配出来,如果想要中间间隔几个也能够被匹配出来,使用slop

public List<String> getPhraseMatch(){
    // 拼接查询条件
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    queryBuilder
        .must(QueryBuilders.matchPhraseQuery("pointName",goodsData.getSearchEsName()));

    // 默认查询999条数据
    Pageable pageable = new PageRequest(0,999);
    
    // 构建查询语句
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withPageable(pageable).build();

    // 查询
    List<String> ids  = elasticsearchTemplate.queryForIds(searchQuery);
    return ids;
}

完全匹配查询

TermQuery, 这个是最严格的查询,完全匹配才查询出来,如上面的例子,完全匹配 id,才查询。

public List<User> getTerm(String name){
    // 构建查询语句
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("name", name)).withPageable(pageable).build();
    return elasticsearchTemplate.queryForList(searchQuery, User.class);
}

多字段匹配某一个值

multiMatchQuery 场景需要多个字段匹配某一个值的情况

public List<User> getMultiMatch(){
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

    // MatchQueryBuilder.Operator.AND 完全匹配到短语的才查询出来,比如 张三,只有张三都出现,才匹配到
    queryBuilder.must(QueryBuilders.multiMatchQuery(searchName, "name", "tagName", "lineName").operator(MatchQueryBuilder.Operator.AND));

    // 构建查询语句,默认查询10条,这里如果使用ES作为搜索,需要考虑分页的情况
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
    Iterable<User> iter = elasticsearchTemplate.queryForPage(searchQuery, User.class);
    return iter;
}

完全包含查询

operator(MatchQueryBuilder.Operator.AND) ,设置分词之后,张三会被分为,张,三,希望张三出现的情况才查询出来,则可以设置这个。

合并查询

BoolQuery,设置多个条件的查询方式,作用是组合多个Query,有四种组合方式 mustmustnotfiltershould ,query查询的时候,会先比较查询条件,然后计算分值,最后返回文档结果;

  • must 相当于 与

    跟mysql的 and作用一样,会参与计算分值

  • mustnot 相当于 非

    跟mysql的not and作用一样,不会参与计算分值

  • should 相当于 或

    跟mysql的 or作用一样,有一个或者多个should子句,那么只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句。

  • filter 过滤

  • 排除掉不需要的数据

public List<User> getBoolQuery(String name,String content){
    // 构建查询
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    queryBuilder.must(QueryBuilders.termQuery("name",name));
    queryBuilder.should(QueryBuilders.matchQuery("content",content));
    
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
    return elasticsearchTemplate.queryForList(searchQuery, User.class);
}

参考网址:https://blog.csdn.net/tianyaleixiaowu/article/details/77965257

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐