ES构建queryBuilder条件查询

开发过程中多使用ES的javaAPI,通过javaAPI来对ES的索引进行操作,对ES的操作一般都是通过构建QueryBuilder对象来进行操作。下面介绍几种QueryBuilder的构建。

1. maven配置

maven依赖

<dependency>
   <groupId>org.elasticsearch</groupId>
   <artifactId>elasticsearch</artifactId>
   <version>6.3.2</version>
</dependency>
<dependency>
   <groupId>org.elasticsearch.client</groupId>
   <artifactId>transport</artifactId>
   <version>6.3.2</version>
</dependency>

2. 等值查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("name", "小李"));

查询name=小李的ES文档,等同于命令:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "must": [{
        "term": {
          "name": {
            "boost": 1.0,
            "value": "小李"
          }
        }
      }],
      "boost": 1.0
    }
  }
}

3. 范围查询

BoolQueryBuilder queryBuilder = QueryBuilders.rangeQuery("age")
                                .gte(18)
                                .lte(50);

查询年龄大于等于18,并且小于等于50的记录,等同于以下命令。

{
  "query": {
    "range": {
      "age": {
        "include_lower": true,
        "include_upper": true,
        "from": 18,
        "boost": 1.0,
        "to": 50
      }
    }
  }
}

4. 模糊查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.wildcardQuery("name", "*小李*"));

查询姓名中包含有小李的的文档记录,等同于以下命令:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "must": [{
        "wildcard": {
          "name": {
            "boost": 1.0,
            "wildcard": "*小李*"
          }
        }
      }],
      "boost": 1.0
    }
  }
}

5. 多条件查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("name", "小李"))
                .must(QueryBuilders.rangeQuery("age")
                        .gte(10)
                        .lte(50));

查询姓名为:小李,并且年龄在10-50之间的文档,等同于以下命令:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "must": [{
        "term": {
          "name": {
            "boost": 1.0,
            "value": "小李"
          }
        }
      }, {
        "range": {
          "age": {
            "include_lower": true,
            "include_upper": true,
            "from": 10,
            "boost": 1.0,
            "to": 50
          }
        }
      }],
      "boost": 1.0
    }
  }
}

6. 集合查询

List<String> list = Arrays.asList("北京", "上海", "杭州");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("name", "李明"))
                .must(QueryBuilders.termsQuery("address", list))
                .must(QueryBuilders.rangeQuery("age")
                        .gte(10)
                        .lte(50));

查询地址在北京、上海、杭州,并且年龄在10至50,名字叫做李明的文档,等同于以下命令:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "must": [{
        "term": {
          "name": {
            "boost": 1.0,
            "value": "李明"
          }
        }
      }, {
        "terms": {
          "address": ["北京", "上海", "杭州"],
          "boost": 1.0
        }
      }, {
        "range": {
          "age": {
            "include_lower": true,
            "include_upper": true,
            "from": 10,
            "boost": 1.0,
            "to": 50
          }
        }
      }],
      "boost": 1.0
    }
  }
}

7. 使用should查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.wildcardQuery("name", "*小李*"))
                .should(QueryBuilders.termQuery("address", "北京"));

查询姓名包含小李或者是地址是北京的记录,should相当于或者or,命令如下:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "should": [{
        "wildcard": {
          "name": {
            "boost": 1.0,
            "wildcard": "*小李*"
          }
        }
      }, {
        "term": {
          "address": {
            "boost": 1.0,
            "value": "北京"
          }
        }
      }],
      "boost": 1.0
    }
  }
}

8. should和must配合查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("sex", "男"))
                .should(QueryBuilders.wildcardQuery("name", "*小李*"))
                .should(QueryBuilders.termQuery("address", "北京"))
                .minimumShouldMatch(1);

查询性别为男,姓名包含小李或地址为北京的记录,**minimumShouldMatch(1)**表示最少要匹配到一个should条件。相当于以下命令:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "should": [{
        "wildcard": {
          "name": {
            "boost": 1.0,
            "wildcard": "*小李*"
          }
        }
      }, {
        "term": {
          "address": {
            "boost": 1.0,
            "value": "北京"
          }
        }
      }],
      "minimum_should_match": "1",
      "must": [{
        "term": {
          "sex": {
            "boost": 1.0,
            "value": "男"
          }
        }
      }],
      "boost": 1.0
    }
  }
}

must:必须满足的条件

should:非必须满足的条件

minimumShouldMatch(1):至少要满足一个 should 条件

以上queryBuilder可以理解为需要满足一个must条件,并且至少要满足一个should条件。

9. 有值查询

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.existsQuery("name"))
                .mustNot(QueryBuilders.existsQuery("tag"));

查询name有值,tag不存在值的文档,命令如下:

{
  "query": {
    "bool": {
      "adjust_pure_negative": true,
      "must_not": [{
        "exists": {
          "field": "tag",
          "boost": 1.0
        }
      }],
      "must": [{
        "exists": {
          "field": "name",
          "boost": 1.0
        }
      }],
      "boost": 1.0
    }
  }
}

10. 分页查询

// 排序字段,可以添加多个排序
SortBuilder sortBuilder = SortBuilders.fieldSort("create_time");
SortOrder sortOrder = SortOrder.DESC;
sortBuilder.order(sortOrder);
queryBuilder.addSort(sortBuilder);
// 分页查询
SearchResponse response = this.transportClient.prepareSearch(index)
                .setTypes(type)
                .setQuery(queryBuilder)
                .setFrom(offset)
                .setSize(rows)
                .setExplain(false)
                .execute()
                .actionGet();

普通分页查询数据,相当于以下命令:

{
    "from":0,
    "size":10,
    "query":{
        "bool":{
            "adjust_pure_negative":true,
            "must":[
                {
                    "term":{
                        "name":{
                            "boost":1,
                            "value":"小李"
                        }
                    }
                }
            ],
            "boost":1
        }
    },
    "_source":{
        "includes":[
            "id",
            "name",
            "age",
            "address",
            "birthday"
        ],
        "excludes":[

        ]
    },
    "sort":[
        {
            "create_time":{
                "order":"desc"
            }
        }
    ]
}

基于scrollId查询的API如下:

SearchResponse scrollResp = null;
        String scrollId = ContextParameterHolder.get("scrollId");
        if (scrollId != null) {
            scrollResp = getTransportClient().prepareSearchScroll(scrollId).setScroll(new TimeValue(60000)).execute()
                    .actionGet();
        } else {
            log.info("基于scroll的分页查询,scrollId为空");
            scrollResp = this.prepareSearch()
                    .setSearchType(SearchType.QUERY_AND_FETCH)
                    .setScroll(new TimeValue(60000))
                    .setQuery(queryBuilder)
                    .setSize(page.getPageSize()).execute().actionGet();
            ContextParameterHolder.set("scrollId", scrollResp.getScrollId());
        }

11. ES脚本查询

String scriptValue= " doc['user_name'].value == '' || doc['user_name'].value == null || (doc['user_name'].value=='测试名称' )";
List<String> list = Arrays.asList("北京", "上海", "杭州");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.filter(QueryBuilders.termsQuery("address", list))
                .filter(QueryBuilders.termQuery("sex", "男"))
                .filter(QueryBuilders.scriptQuery(new Script(String.valueOf(scriptValue))));

通过自定义ES脚本查询数据,相当于以下命令:

{
    "from":0,
    "size":1,
    "query":{
        "bool":{
            "filter":{
                "bool":{
                    "filter":[
                        {
                            "term":{
                                "sex":"男"
                            }
                        },
                        {
                            "terms":{
                                "address":[
                                    "北京","上海","杭州"
                                ]
                            }
                        },
                        {
                            "script":{
                                "script":{
                                    "inline":" doc['user_name'].value == '' || doc['user_name'].value == null || (doc['user_name'].value == '测试名称' )"
                                }
                            }
                        }
                    ]
                }
            }
        }
    },
    "_source":{
        "includes":[
            "id",
            "user_name",
            "sex",
            "address",
            "age",
            "birthday"
        ],
        "excludes":[

        ]
    }
}
  • 29
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值