elasticsearchRestTemplate查询:termQuery、matchQuery、rangeQuery、fuzzyQuery、matchAllQuery、multiMatchQuery

注意:本文使用 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;
	}


上一篇:run keyword if


下一篇:ES-索引规范