开发过程中多使用ES的javaAPI,通过javaAPI来对ES的索引进行操作,对ES的操作一般都是通过构建QueryBuilder对象来进行操作。下面介绍几种QueryBuilder的构建。
maven依赖
org.elasticsearch
elasticsearch
6.3.2
org.elasticsearch.client
transport
6.3.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
}
}
}
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
}
}
}
}
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.wildcardQuery("name", "*小李*"));
查询姓名中包含有小李的的文档记录,等同于以下命令:
{
"query": {
"bool": {
"adjust_pure_negative": true,
"must": [{
"wildcard": {
"name": {
"boost": 1.0,
"wildcard": "*小李*"
}
}
}],
"boost": 1.0
}
}
}
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
}
}
}
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
}
}
}
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
}
}
}
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条件。
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
}
}
}
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.0,
"value": "小李"
}
}
}],
"boost": 1.0
}
}
}
基于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());
}