一、Elasticsearch的复杂查询案例

1 match查询

match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。

query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。

  1. Kibana代码
GET /java06/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发"
      }
    }
  }
}
  1. operator:
GET /java06/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发",
        "operator": "and"
      }
    }
  }
}

上边的搜索的执行过程是:
1、将“spring开发”分词,分为spring、开发两个词
2、再使用spring和开发两个词去匹配索引中搜索。
3、由于设置了operator为and,必须匹配两个词成功时才返回该文档。

  1. 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字段

  1. 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的文档

  1. Kibana代码
GET /java06/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        },
        {
          "range": {
            "price": {
              "gte": 50,
              "lte": 100
            }
          }
        }
      ]
    }
  }
}
  1. 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需要计算相关度分数:

  1. Kibana代码
GET /java06/course/_search
{
  "query": {
     "bool" : {
        "must":[
            {
               "match": {
                 "name": "开发"
               }
            },
            {
              "range": {# 范围, 字段的数据必须满足某范围才有结果。
                "price": {
                  "gte": 10, # 比较符号 lt gt lte gte
                  "lte": 100
                }
              }
            }
        ]
     }
  }
}
  1. 使用 filter, price不需要计算相关度分数:
GET /java06/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        }
      ],
      "filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。
        "range": {
          "price": {
            "gte": 1,
            "lte": 100
          }
        }
      }
    }
  }
}
  1. 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查询

高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。

例如:

  1. Kibana代码
GET /java06/course/_search
{
  "query": {
    "match": {
      "name": "开发"
    }
  },
  "highlight": {
      "pre_tags": ["<font color='red'>"],
      "post_tags": ["</font>"],
      "fields": {"name": {}}
  }
}
  1. 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 状态的。

打开两台查看颜色,注意主分片的位置。
主主备备分片组合也是可以的

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐