当前位置: 首页 > 工具软件 > QueryBuilder > 使用案例 >

ES构建queryBuilder条件查询

姜淇
2023-12-01

开发过程中多使用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. 分页查询

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());
        }
 类似资料: