Elasticsearch的复杂查询案例
一、Elasticsearch的复杂查询案例
1 match查询
match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。
query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。
- Kibana代码
GET /java06/course/_search { "query" : { "match" : { "name": { "query": "spring开发" } } } }
- operator:
GET /java06/course/_search { "query" : { "match" : { "name": { "query": "spring开发", "operator": "and" } } } }
上边的搜索的执行过程是:
1、将“spring开发”分词,分为spring、开发两个词
2、再使用spring和开发两个词去匹配索引中搜索。
3、由于设置了operator为and,必须匹配两个词成功时才返回该文档。
- Java代码
@Test public void testMatchQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring开 发").operator(Operator.AND)); // 设置搜索源 searchRequest.source(searchSourceBuilder); // 执行搜索 searchResponse = restHighLevelClient.search(searchRequest); }
2 multi_match查询
matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。
1、基本使用
例子:关键字 “开发”去匹配name 和description字段
- Kibana代码
GET /java06/course/_search { "query": { "multi_match": { "query": "开发", "fields": ["name","description"] } } }
注意:此搜索操作适合构建复杂查询条件,生产环境常用。
2. Java代码
public void testMultiMatchQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.multiMatchQuery("开发","name","description")); // 设置搜索源 searchRequest.source(searchSourceBuilder); // 执行搜索 searchResponse = restHighLevelClient.search(searchRequest); }
3 bool查询
布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
参数:
must:表示必须,多个查询条件必须都满足。(通常使用must)
should:表示或者,多个查询条件只要有一个满足即可。
must_not:表示非。(不常用)
例如:查询name包括“开发”并且价格区间是1-100的文档
- Kibana代码
GET /java06/course/_search { "query": { "bool": { "must": [ { "match": { "name": "开发" } }, { "range": { "price": { "gte": 50, "lte": 100 } } } ] } } }
- Java代码
public void testBooleanMatch() throws IOException { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //json条件 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发")); boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte("50").lte(100)); searchSourceBuilder.query(boolQueryBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest); }
4 filter查询
过滤查询。此操作实际上就是 query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。
如:使用bool查询,搜索 name中包含 "开发"的数据,且price在 10~100 之间
1、不使用 filter, name和price需要计算相关度分数:
- Kibana代码
GET /java06/course/_search { "query": { "bool" : { "must":[ { "match": { "name": "开发" } }, { "range": {# 范围, 字段的数据必须满足某范围才有结果。 "price": { "gte": 10, # 比较符号 lt gt lte gte "lte": 100 } } } ] } } }
- 使用 filter, price不需要计算相关度分数:
GET /java06/course/_search { "query": { "bool": { "must": [ { "match": { "name": "开发" } } ], "filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。 "range": { "price": { "gte": 1, "lte": 100 } } } } } }
- Java代码
public void testFilterQuery() throws IOException { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发")); boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(10).lte(100)) searchSourceBuilder.query(boolQueryBuilder); searchRequest.source(searchSourceBuilder); searchResponse = restHighLevelClient.search(searchRequest); }
5 highlight查询
高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。
例如:
- Kibana代码
GET /java06/course/_search { "query": { "match": { "name": "开发" } }, "highlight": { "pre_tags": ["<font color='red'>"], "post_tags": ["</font>"], "fields": { "name": { }} } }
- Java代码
//查询 public void testHighLightQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring")); //设置高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<font color='red'>"); highlightBuilder.postTags("</font>"); highlightBuilder.fields().add(new HighlightBuilder.Field("name")); searchSourceBuilder.highlighter(highlightBuilder); searchRequest.source(searchSourceBuilder); searchResponse = restHighLevelClient.search(searchRequest); } //遍历 @After public void displayDoc() { SearchHits searchHits = searchResponse.getHits(); long totalHits = searchHits.getTotalHits(); System.out.println("共搜索到" + totalHits + "条文档"); SearchHit[] hits = searchHits.getHits(); for (int i = 0; i < hits.length; i++) { SearchHit hit = hits[i]; String id = hit.getId(); System.out.println("id:" + id); String source = hit.getSourceAsString(); System.out.println(source); Map<String, HighlightField> highlightFields = hit.getHighlightFields(); if (highlightFields != null) { HighlightField highlightField = highlightFields.get("name"); Text[] fragments = highlightField.getFragments(); System.out.println("高亮字段:" + fragments[0].toString()); } } }
二、Elasticsearch集群搭建
1.克隆上一篇文章的ES虚拟机
2. 修改elasticsearch.yml内容如下
node.name: power_shop_node_2 discovery.zen.ping.unicast.hosts: ["192.168.204.132:9300", "192.168.204.133:9300"]
3.删除节点2的data目录
4.测试(haed)
status:用三种颜色来展示健康状态
green:索引库的每个 primary shard 和 replica shard 都是 active 的
yellow:索引库的每个 primary shard 都是 active 的,但部分的 replica shard 不是 active 的,如单节点创建
备份分配
red:不是所有的 primary shard 都是 active 状态的。
打开两台查看颜色,注意主分片的位置。
主主备备分片组合也是可以的
#Java开发#