es QueryBuilders

基本查询
先来熟QueryBuilders这个类封装的基本查询

QueryBuilders.matchQuery() 会根据分词器进行分词,分词之后去查询
QueryBuilders.termQuery() 不会进行分词,且完全等于才会匹配
QueryBuilders.termsQuery() 一个字段匹配多个值,where name = ‘A’ or name = ‘B’
QueryBuilders.multiMatchQuery() 会分词 一个值对应多个字段 where username = ‘zs’ or password = ‘zs’
QueryBuilders.matchPhraseQuery() 不会分词,当成一个整体去匹配,相当于 %like%
如果想使用一个字段匹配多个值,并且这多个值是and关系,如下 要求查询的数据中必须包含北京‘和’天津QueryBuilders.matchQuery(“address”,“北京 天津”).operator(Operator.AND)
如果想使用一个字段匹配多个值,并且这多个值是or关系,如下 要求查询的数据中必须包含北京‘或’天津
QueryBuilders.matchQuery(“address”,“北京 天津”).operator(Operator.OR)
复合查询
通常都是将多个查询条件组合在一起,常用的有must、must_not、should

测试数据
有这样一段测试数据
      {"address":"鸿星尔克0","codes":"中国人民银行0","id":0,"name":"平安富士康0"}
     {"address":"鸿星尔克1","codes":"中国人民银行1","id":1,"name":"平安富士康1"}
     {"address":"鸿星尔克2","codes":"中国人民银行2","id":2,"name":"平安富士康2"}
     {"address":"鸿星尔克3","codes":"中国人民银行3","id":3,"name":"平安富士康3"}
     {"address":"鸿星尔克4","codes":"中国人民银行4","id":4,"name":"平安富士康4"}
     {"address":"汽车家族0","id":0,"name":"快递收货0"}
     {"address":"汽车家族1","id":1,"name":"快递收货1"}
     {"address":"汽车家族2","id":2,"name":"快递收货2"}
     {"address":"汽车家族3","id":3,"name":"快递收货3"}
     {"address":"汽车家族4","id":4,"name":"快递收货4"}
     {"address":"新鲜水果-徐鲸鱼0","id":0,"name":"东方不败0"}
     {"address":"新鲜水果-徐鲸鱼1","id":1,"name":"东方不败1"}
     {"address":"新鲜水果-徐鲸鱼2","id":2,"name":"东方不败2"}
     {"address":"新鲜水果-徐鲸鱼3","id":3,"name":"东方不败3"}
     {"address":"新鲜水果-徐鲸鱼4","id":4,"name":"东方不败4"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
查询1:查询address 必须包含’汽车’ 或者’水果’的,查询id必须不能包含’2’和’0’的。
此时需要构造两个条件,类似mysql中的 where (address like %汽车% or
address like %水果% ) and (id != 1 or id != 2)
    @Test
    public void testBoolQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
        boolQuery.mustNot(QueryBuilders.termsQuery("id","0","2"));
        searchSourceBuilder.query(boolQuery);

        searchRequest.source(searchSourceBuilder);

        SearchResponse search = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
        for (SearchHit documentFields : search.getHits().getHits()) {
            System.out.println(documentFields.getScore() + ":::"  +documentFields.getSourceAsString());
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
查看日志打印

为什么address中包含汽车的得分高于包含水果的,因为包含汽车的address字段的值有5个字符,包含水果的address字段值包含9个字符,字符越少的,得分越高。

之前在must条件中是这么写的

后来发现一直查不到数据,发现这样写不对,我们查询需求是:address必须包含‘汽车’或者‘水果的’,但如果这样写的话就成了address中既要匹配‘水果’又要匹配,显然没有哪个address字段值既包含水果又包含汽车的,所以查询不到。

查询2:查询address 必须包含’汽车’ 或者’水果’的,查询id必须不能包含’2’和’0’的。name最好是包含 '东方’的。这个最好包含是有最好,没有也无所谓,此时需要用should来封装。
    @Test
    public void testBoolQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
        boolQuery.mustNot(QueryBuilders.termsQuery("id","0","2"));
        boolQuery.should(QueryBuilders.matchQuery("name","东方"));
        searchSourceBuilder.query(boolQuery);
        
        searchRequest.source(searchSourceBuilder);

        SearchResponse search = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
        for (SearchHit documentFields : search.getHits().getHits()) {
            System.out.println(documentFields.getScore() + ":::"  +documentFields.getSourceAsString());
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
查看日志

此时,在should中指定的条件name中包含东方的,分数就提高了。

如果我们将must条件修改为一下,则还是会查询不到数据,因为没有一条文档的address包含‘汽车’或‘水果’同时codes包含‘中国’


复合查询嵌套
boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
1
在复合查询时,我们使用must构建了 address必须包含‘汽车’或‘水果’的查询条件,但我们也可以给这个must再嵌套一个布尔查询,这个bool查询应该是一个should关系,如下

    private BoolQueryBuilder buildBoolQuery(){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchQuery("address","水果"));
        boolQueryBuilder.should(QueryBuilders.matchQuery("address","汽车"));
        return boolQueryBuilder;
    }
1
2
3
4
5
6
修改must构造即可。

————————————————
版权声明:本文为CSDN博主「DanceDonkey」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43750656/article/details/112002929

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch QueryBuilders 是 Elasticsearch Java 客户端提供的一组构建查询的工具类。其中包括了各种类型的查询,如 TermQueryMatchQuery、BoolQuery 等等。在使用 QueryBuilders 进行查询时,我们可以通过链式调用的方式,使用不同的查询方法来构建我们需要的查询语句。 在使用 QueryBuilders 进行查询时,我们可以通过以下步骤来实现: 1. 创建一个 SearchRequest 对象,并设置需要查询的索引名称。 2. 创建一个 SearchSourceBuilder 对象,并设置需要查询的条件和过滤器。 3. 调用 SearchRequest 的 source 方法,将 SearchSourceBuilder 对象设置为查询条件。 4. 调用 Elasticsearch 客户端的 search 方法,执行查询并获取结果。 下面是一个示例代码,展示了使用 QueryBuilders 进行 TermQuery 查询的方法: ``` SearchRequest searchRequest = new SearchRequest("index_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.termQuery("field_name", "search_term")); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); ``` 在上面的代码中,我们使用了 TermQuery 方法来创建一个精确匹配查询。该查询会查找指定字段中包含指定搜索词的文档,并将结果返回给我们。通过调整 QueryBuilders 中不同的查询方法,我们可以实现更加复杂的查询操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值