注意:本文使用 Springboot 2.4.3,、RestHighLevelClient,elasticsearch使用的是 7.9.3
/**
* 查询所有文档
* {"from":0,"size":10000,"query":{"match_all":{"boost":1.0}},"version":true}
*
* @return
*/
@GetMapping("/matchAllQuery")
public Object matchAllQuery() {
NativeSearchQuery matchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).build();
SearchHits<Brand> searchHits = elasticsearchRestTemplate.search(matchQuery, Brand.class);
return searchHits;
}
/**
* 根据搜索关键字查询文档,搜索关键字不分词
* {"from":0,"size":10000,"query":{"term":{"name":{"value":"小米","boost":1.0}}},"version":true}
*
* @param keyword
* @return
*/
@GetMapping("/termQuery")
public Object termQuery(String keyword) {
NativeSearchQuery termQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(termQuery, Brand.class);
return search;
}
/**
* 根据搜索关键字分词后的字段搜索文档
* 关键字会分词,其实该方式等价于matchQuery
* {
* "from": 0,
* "size": 10000,
* "query": {
* "common": {
* "name": {
* "query": "宇华华为",
* "high_freq_operator": "OR",
* "low_freq_operator": "OR",
* "cutoff_frequency": 0.01,
* "boost": 1.0
* }* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/commonTermsQuery")
public Object commonTermsQuery(String keyword) {
NativeSearchQuery commonTermsQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.commonTermsQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(commonTermsQuery, Brand.class);
return search;
}
/**
* 模糊匹配、接近匹配
* 查询包含搜索关键字 分词后的字段 的数据
* 查询关键字会分词
* {
* "from": 0,
* "size": 10000,
* "query": {
* "match": {
* "name": {
* "query": "中华华为",
* "operator": "OR",
* "prefix_length": 0,
* "max_expansions": 50,
* "fuzzy_transpositions": true,
* "lenient": false,
* "zero_terms_query": "NONE",
* "auto_generate_synonyms_phrase_query": true,
* "boost": 1.0
* }* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/matchQuery")
public Object matchQuery(String keyword) {
NativeSearchQuery matchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(matchQuery, Brand.class);
return search;
}
/**
* 精确匹配查询,搜索关键字不分词 ,针对的是一个语句
*
* @param keyword
* @return
*/
@GetMapping("/matchPhraseQuery")
public Object matchPhraseQuery(String keyword) {
NativeSearchQuery matchPhraseQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(matchPhraseQuery, Brand.class);
return search;
}
/**
* 这种精准查询满足的条件有点苛刻,有时我们想要包含 ""广东靓仔靓女"" 的文档也能够匹配 "广东靓女"。这时就要以用到 "slop" 参数来控制查询语句的灵活度。
* slop 表示相隔多远时,还能匹配到。比如 搜索关键字为 广东靓女,设置slop为2,表示中间可以相隔为2,所以广东靓仔靓女这条数据也是满足条件的
* {
* "from": 0,
* "size": 10000,
* "query": {
* "match_phrase": {
* "name": {
* "query": "广东靓女",
* "slop": 2,
* "zero_terms_query": "NONE",
* "boost": 1.0
* }* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/matchPhraseQueryWithSlop")
public Object matchPhraseQueryWithSlop(String keyword) {
NativeSearchQuery matchPhraseQueryWithSlop = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("name", keyword).slop(2)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(matchPhraseQueryWithSlop, Brand.class);
return search;
}
/**
* 跟matchPhrase作用大致相同,会先进行一次matchPhrase查询,然后根据分词后的最后一个词汇作为前缀模糊查询
* 举个例子:查询列的值: this is a handsome boy ,查询关键字: this is a hand
* es 先进行一次matchPhrase查询筛选出 含有this is a hand 的文档,然后进一步查询 以 hand 开头的数据,如 this is a handsome boy 会命中
* {
* "from": 0,
* "size": 10000,
* "query": {
* "match_phrase_prefix": {
* "name": {
* "query": "宇华华为",
* "slop": 0,
* "max_expansions": 50,
* "boost": 1.0
* }* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/matchPhrasePrefixQuery")
public Object matchPhrasePrefixQuery(String keyword) {
NativeSearchQuery matchPhrasePrefixQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhrasePrefixQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(matchPhrasePrefixQuery, Brand.class);
return search;
}
/**
* 根据搜索关键查询文档
* 搜索关键字不分词,测出仅支持单个字去查询?这个的作用还有待验证
*
* @param keyword
* @return
*/
@GetMapping("/prefixQuery")
public Object prefixQuery(String keyword) {
NativeSearchQuery prefixQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.prefixQuery("name", keyword)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(prefixQuery, Brand.class);
return search;
}
/**
* 从多个列中查询包含搜索关键字分词后的字段的数据:如中华华为分词后的字段大概有:中华、华为、华,会从name、brandName、subTile三个列搜索包含分词后的字段的数据
* {
* "from": 0,
* "size": 10000,
* "query": {
* "multi_match": {
* "query": "中华华为",
* "fields": ["brandName^1.0", "name^1.0", "subTitle^1.0"],
* "type": "best_fields",
* "operator": "OR",
* "slop": 0,
* "prefix_length": 0,
* "max_expansions": 50,
* "zero_terms_query": "NONE",
* "auto_generate_synonyms_phrase_query": true,
* "fuzzy_transpositions": true,
* "boost": 1.0
* }* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/multiMatchQuery")
public Object multiMatchQuery(String keyword) {
NativeSearchQuery multiMatchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "subTitle", "brandName")).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(multiMatchQuery, Brand.class);
return search;
}
/**
* 范围查询
* {
* "from": 0,
* "size": 10000,
* "query": {
* "range": {
* "id": {
* "from": 100,
* "to": null,
* "include_lower": false,
* "include_upper": true,
* "boost": 1.0
* }* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/rangeQuery")
public Object rangeQuery(String keyword) {
NativeSearchQuery rangeQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.rangeQuery("id").gt(100)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(rangeQuery, Brand.class);
return search;
}
/**
* 根据正则表达式查询
*
* @param keyword
* @return
*/
@GetMapping("/regexpQuery")
public Object regexpQuery(String keyword) {
NativeSearchQuery regexpQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.regexpQuery("name", "正则表达式")).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(regexpQuery, Brand.class);
return search;
}
/**
* 对多个查询的结果做去重合并
* <p>
* {
* "from": 0,
* "size": 10000,
* "query": {
* "dis_max": {
* "tie_breaker": 0.0,
* "queries": [{
* "match": {
* "name": {
* "query": "华",
* "operator": "OR",
* "prefix_length": 0,
* "max_expansions": 50,
* "fuzzy_transpositions": true,
* "lenient": false,
* "zero_terms_query": "NONE",
* "auto_generate_synonyms_phrase_query": true,
* "boost": 1.0
* }* }
* }, {
* "term": {
* "name": {
* "value": "华为",
* "boost": 1.0
* }
* }
* }],
* "boost": 0
* }
* },
* "version": true
* }
*
* @param keyword
* @return
*/
@GetMapping("/disMaxQuery")
public Object disMaxQuery(String keyword) {
NativeSearchQuery disMaxQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.disMaxQuery().add(QueryBuilders.matchQuery("name", keyword)).add(QueryBuilders.termQuery("name", "华为"))).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(disMaxQuery, Brand.class);
return search;
}
/**
* 实际的搜索中,我们有时候会打错字,从而导致搜索不到。在Elasticsearch中,我们可以使用fuzziness属性来进行模糊查询,从而达到搜索有错别字的情形。
* match查询具有“fuziness”属性。它可以被设置为“0”, “1”, “2”或“auto”。“auto”是推荐的选项,它会根据查询词的长度定义距离。
* 简单的说,就是搜索关键有错别字,es可以会自动进行纠错,假如查询列的数据是周星驰,但用户搜索的时候输入的是周星迟,fuzzyQuery可以将正确的数据查询出来
*
* 搜索华未会将华为的数据搜索出来
* {
* "from": 0,
* "size": 10000,
* "query": {
* "fuzzy": {
* "name": {
* "value": "华未",
* "fuzziness": "1",
* "prefix_length": 0,
* "max_expansions": 50,
* "transpositions": true,
* "boost": 1.0
* }* }
* },
* "version": true
* }
* @param keyword
* @return
*/
@GetMapping("/fuzzyQuery")
public Object fuzzyQuery(String keyword) {
// 默认是auto,修改为只允许修正一个错别字
NativeSearchQuery fuzzyQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.fuzzyQuery("name", keyword).fuzziness(Fuzziness.ONE)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(fuzzyQuery, Brand.class);
return search;
}
/**
* 轻量级字符串搜索,关键字会分词
* @param keyword
* @return
*/
@GetMapping("/queryStringQuery")
public Object queryStringQuery(String keyword) {
// 默认是auto,修改为只允许修正一个错别字
NativeSearchQuery queryStringQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(keyword).fuzziness(Fuzziness.ONE)).build();
SearchHits<Brand> search = elasticsearchRestTemplate.search(queryStringQuery, Brand.class);
return search;
}