Elasticsearch使用QueryBuilder查询(附带实例)
QueryBuilder 是一个功能强大的多条件查询构建工具,可以构建出各种各样的查询条件。
通过构建 QueryBuilder 可以实现各种查询功能,比如精确查询、模糊查询、范围查询等。下面通过示例演示这几种查询的实现。
1) 左右模糊,使用 queryStringQuery 实现左右模糊查询:
2) 前缀查询,如果字段没分词,就匹配整个字段前缀。
3) 分词模糊查询,通过增加 fuzziness 模糊属性进行查询,如能够匹配 hotelName 为 tel 前或后加一个字母的文档,fuzziness 的含义是检索的 term 前后增加或减少 n 个单词的匹配查询。
4) 通配符查询,使用 wildcardQuery 进行通配符查询,“*”表示任意字符串,“?”表示任意一个字符。
通过构建 QueryBuilder 可以实现各种查询功能,比如精确查询、模糊查询、范围查询等。下面通过示例演示这几种查询的实现。
QueryBuilder精确查询
精确查询指的是查询关键字(或者关键字分词后)必须与目标分词结果完全匹配。1) 单条件匹配
// 不分词查询,参数1:字段名,参数2:字段查询值,因为不分词,所以只能查询一个汉字,而英文可以查询一个单词 QueryBuilder termQuery=QueryBuilders.termQuery("bookName", "三"); // 分词查询,采用默认的分词器 QueryBuilder matchQuery = QueryBuilders.matchQuery("author", "明朝");在上面的示例中,使用 termQuery 为不分词查询,而 matchQuery 为分词模糊查询,并采用默认的分词器。
2) 多条件匹配
// 不分词查询,参数1:字段名,参数2:多个字段查询值,因为不分词,所以只能查询一个汉字,而英文可以查询一个单词 QueryBuilder termsQuery=QueryBuilders.termsQuery("bookName", "明","三"); // 分词查询,采用默认的分词器 QueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("明朝", "author","bookName");在上面的示例中,termsQuery 和 termQuery 的功能类似,支持传入多个参数。multiMatchQuery 多个匹配其实就是传入多个值进行匹配查询。
QueryBuilder模糊查询
模糊查询是指查询关键字与目标关键字进行模糊匹配。1) 左右模糊,使用 queryStringQuery 实现左右模糊查询:
// 左右模糊 QueryBuilder queryStringQuery = QueryBuilders.queryStringQuery("明").field("bookName");
2) 前缀查询,如果字段没分词,就匹配整个字段前缀。
QueryBuilders.prefixQuery("bookName","明");
3) 分词模糊查询,通过增加 fuzziness 模糊属性进行查询,如能够匹配 hotelName 为 tel 前或后加一个字母的文档,fuzziness 的含义是检索的 term 前后增加或减少 n 个单词的匹配查询。
// fuzzy query:分词模糊查询,通过增加fuzziness 模糊属性来查询,如能够匹配bookName为"明"前或后加一个字母的文档,fuzziness的含义是检索的term前后增加或减少n个单词的匹配查询 QueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("bookName","明").fuzziness(Fuzziness.ONE);
4) 通配符查询,使用 wildcardQuery 进行通配符查询,“*”表示任意字符串,“?”表示任意一个字符。
// wildcard Query:通配符查询,支持“*”表示任意字符串,“?”表示任意一个字符 QueryBuilder fuzzyQuery = QueryBuilders.wildcardQuery("bookName","明*"); // 前面是fieldname,后面是带匹配字符的字符串 QueryBuilder fuzzyQuery = QueryBuilders.wildcardQuery("bookName","三?");需要注意的是,在分词的情况下,fuzzyQuery、prefixQuery、wildcardQuery不支持分词查询,即使有这种文档数据,也不一定能查询出来。
QueryBuilder范围查询
QueryBuilders 通过 rangeQuery 方法实现价格、年龄等字段的范围查询,示例代码如下:// 价格范围查询,默认闭区间查询 QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("price").from("50").to("50"); // 价格范围查询,开区间查询 QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("price").from("40").to("60").includeUpper(false).includeLower(false);// 默认是true,也就是包含 // 价格范围查询,大于60 QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("price").gt("60"); // 价格范围查询,大于等于60 QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("price").gte("60"); // 价格范围查询,小于60 QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("price").lt("60"); // 价格范围查询,小于等于60 QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("price").lte("60");从上面的示例可以看到,QueryBuilders 提供了 from、to、gt、lt 等方法实现范围查询和数据比较等功能。from、to 用于实现范围查询;gt、gte、lt、lte用于数字比较,实现数字、时间等类型字段的范围查询;includeUpper 包含大于和小于,默认为 true,也就是包含。
QueryBuilder多个关键字的组合查询
QueryBuilders 通过 BoolQuery 实现多个关键字的组合查询,BoolQuery 提供了如下方法实现条件的组合:- must():必须完全匹配条件,相当于 and;
- mustNot():关键字不匹配条件,相当于 not;
- should():至少满足一个条件,这个文档就符合 should,相当于 or。
@Test public void testBoolQuery() { NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.boolQuery() .should(QueryBuilders.termQuery("bookName", "史")) .should(QueryBuilders.termQuery("author", "明")) ) .withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)) .withPageable(PageRequest.of(0, 50)) .build(); Iterable<Book> books = repository.search(nativeSearchQuery); for (Book b : books){ System.out.println(b); } }在上面的示例中,通过 QueryBuilders 构建多个关键字组合查询,查询 bookName 包含关键字“史”或者 author 包含关键字“明”。