• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Elasticsearch 学习+SpringBoot教程三

武飞扬头像
桂亭亭
帮助1

需要学习基础的可参照这两文章

Elasticsearch 学习 SpringBoot实战教程(一)

Elasticsearch 学习 SpringBoot实战教程(二)  

前言: 经过了前面2课的学习我们已经大致明白了ES怎么使用,包括原生语句,javaapi等等,现在我们要在业务中使用了,

所以我们选择spring-data作为我们的ORM框架,快速开发代码。

同时需要给规范化操作

目录

0 前辈动作

1 Springboot项目引入依赖

2 建立目录与文件

3 配置文件

 4 实体类

1 使用ElasticsearchOperations的方式

新增文档

更新文档 

删除文档

查询所有

查询指定id

分页 指定条件 高亮显示 排序 过滤结果

2 使用RestHighLevelClient的方式

精确查询

分页查询

字符匹配AND精准查询

编辑字符匹配OR精准查询

模糊查询


0 前置动作

1 Springboot项目引入依赖

注意你的ES版本号

  1.  
    <dependency>
  2.  
    <groupId>org.springframework.boot</groupId>
  3.  
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4.  
    </dependency>
  5.  
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  6.  
    <dependency>
  7.  
    <groupId>com.alibaba</groupId>
  8.  
    <artifactId>fastjson</artifactId>
  9.  
    <version>2.0.20</version>
  10.  
    </dependency>
  11.  
    <dependency>
  12.  
    <groupId>org.elasticsearch.client</groupId>
  13.  
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
  14.  
    <version>7.10.1</version>
  15.  
    <exclusions>
  16.  
    <exclusion>
  17.  
    <groupId>org.elasticsearch</groupId>
  18.  
    <artifactId>elasticsearch</artifactId>
  19.  
    </exclusion>
  20.  
    </exclusions>
  21.  
    </dependency>
  22.  
    <dependency>
  23.  
    <groupId>org.elasticsearch</groupId>
  24.  
    <artifactId>elasticsearch</artifactId>
  25.  
    <version>7.10.1</version>
  26.  
    </dependency>
学新通

2 建立目录与文件

学新通

 学新通

学新通

学新通

3 配置文件

学新通

  1.  
    spring:
  2.  
    elasticsearch:
  3.  
    uris: localhost:9200
  4.  
    connection-timeout: 3000
  5.  
    socket-timeout: 5000

 4 实体类

  1.  
    package com.example.eslearn.entity;
  2.  
     
  3.  
    import org.springframework.data.annotation.Id;
  4.  
    import org.springframework.data.elasticsearch.annotations.Document;
  5.  
    import org.springframework.data.elasticsearch.annotations.Field;
  6.  
    import org.springframework.data.elasticsearch.annotations.FieldType;
  7.  
     
  8.  
    import java.io.Serializable;
  9.  
     
  10.  
    /**
  11.  
    * Document: 将这个类对象转为 es 中一条文档进行录入
  12.  
    * indexName: 用来指定文档的索引名称
  13.  
    * createIndex: 用来指定是否创建索引,默认为false
  14.  
    */
  15.  
    @Document(indexName = "user", createIndex = true)
  16.  
    public class UserDocument implements Serializable {
  17.  
    @Id // 用来将放入对象id值作为文档_id进行映射
  18.  
    private String id;
  19.  
    @Field(type = FieldType.Keyword) // 字段映射类型
  20.  
    private String name;
  21.  
    private String sex;
  22.  
    private Integer age;
  23.  
    @Field(type = FieldType.Text) // 字段映射类型
  24.  
     
  25.  
    private String city;
学新通

1 使用ElasticsearchOperations的方式

优点:更想我们的springdata的使用风格,简单,快捷,个人使用

新增文档

  1.  
    private final ElasticsearchOperations ESO;
  2.  
    // set方法注入
  3.  
    @Autowired
  4.  
    public CRUDService2(ElasticsearchOperations elasticsearchOperations) {
  5.  
    this.ESO = elasticsearchOperations;
  6.  
    }
  7.  
    // 新增文档
  8.  
    public String save() {
  9.  
    UserDocument user = new UserDocument();
  10.  
    user.setName("说不定看见的");
  11.  
    user.setCity("北京 上海 西安");
  12.  
    user.setAge(22);
  13.  
    user.setSex("男");
  14.  
    UserDocument save = ESO.save(user);
  15.  
    System.out.println(save);
  16.  
    return JSON.toJSONString(save);
  17.  
    }
学新通

学新通

 使用可视化软件查询,得到下面的结果  

学新通学新通

更新文档 

  1.  
    // 更新文档
  2.  
    public String update() {
  3.  
    UserDocument user = new UserDocument();
  4.  
    user.setId("W7w2HYcB32f1ZLmxRwzw");
  5.  
    user.setName("说快来打见的");
  6.  
    user.setCity("北京 上海 西安");
  7.  
    user.setAge(21);
  8.  
    user.setSex("女");
  9.  
    UserDocument save = ESO.save(user);
  10.  
    System.out.println(save);
  11.  
    return JSON.toJSONString(save);
  12.  
    }

学新通

学新通

删除文档

  1.  
    // 删除
  2.  
    public String delete(){
  3.  
    UserDocument userDocument = new UserDocument();
  4.  
    userDocument.setId("8966e506-1763-4d4b-bf1c-4f5d9bd9b052");
  5.  
    return ESO.delete(userDocument);
  6.  
    }

学新通

查询所有

  1.  
    // 查询所有
  2.  
    public String findAll(){
  3.  
    //查询所有
  4.  
    SearchHits<UserDocument> search = ESO.search(Query.findAll(), UserDocument.class);
  5.  
    for (SearchHit<UserDocument> uc : search) {
  6.  
    System.out.println(uc.getContent());
  7.  
    }
  8.  
    return JSON.toJSONString(search);
  9.  
    }

学新通

查询指定id

  1.  
    // 根据id查询文档
  2.  
    public String getById(){
  3.  
    UserDocument userDocument = ESO.get("W7w2HYcB32f1ZLmxRwzw", UserDocument.class);
  4.  
    return JSON.toJSONString(userDocument);
  5.  
    }

学新通

分页 指定条件 高亮显示 排序 过滤结果

服务层

  1.  
    //大杂烩,一次学会
  2.  
    public String findSource(){
  3.  
    //查询条件构建
  4.  
    MatchQueryBuilder mp=new MatchQueryBuilder("name","妲己");
  5.  
     
  6.  
    //排序构建
  7.  
    FieldSortBuilder f = new FieldSortBuilder("age");
  8.  
    //分页构建
  9.  
    Pageable page= PageRequest.of(0,5);
  10.  
    // 高亮构建
  11.  
    HighlightBuilder highlightBuilder = new HighlightBuilder()
  12.  
    .preTags("<span style='color:yellow'>")
  13.  
    .postTags("</span>")
  14.  
    .field("name");
  15.  
    //结果过滤构建,相当于返回那些字段
  16.  
    FetchSourceFilter filter = new FetchSourceFilter(new String[]{"name", "city"}, null);
  17.  
    //查询语句构建
  18.  
    NativeSearchQueryBuilder query = new NativeSearchQueryBuilder()
  19.  
    .withQuery(mp)
  20.  
    .withSorts(f)
  21.  
    .withPageable(page)
  22.  
    .withHighlightBuilder(highlightBuilder)
  23.  
    .withSourceFilter(filter);
  24.  
    //执行查询
  25.  
    SearchHits<UserDocument> search = ESO.search(query.build(), UserDocument.class);
  26.  
    return JSON.toJSONString(search);
  27.  
    }
学新通

控制器

  1.  
    @GetMapping("/findSource")
  2.  
    private String findSource(){
  3.  
    return sv.findSource();
  4.  
    }

学新通

2 使用RestHighLevelClient的方式

优点:安全,企业级常用

什么是BoolQueryBuilder?

BoolQueryBuilder是该客户端库中的一个查询构建器,用于构建布尔查询(bool query)。 布尔查询是一种复合查询,可以将多个查询条件组合在一起。

BoolQueryBuilder提供了几种方法来构建布尔查询:

1. must(QueryBuilders): 添加一个“必须匹配”(must)的查询条件。这意味着文档必须满足该查询条件才能被返回。 相当于sql中的and

2. mustNot(QueryBuilders): 添加一个“不能匹配”(must not)的查询条件。这意味着文档不能满足该查询条件才能被返回。相当于 is not 

3. should(QueryBuilders): 添加一个“应该匹配”(should)的查询条件。这意味着文档可以满足该查询条件,但不是必须的。 相当与or

4. filter(QueryBuilders): 添加一个“过滤”(filter)的查询条件。与must查询条件类似,但过滤查询不会计算相关性得分,通常用于对结果进行筛选。相当与select 的字段

简单的复合查询

  1.  
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
  2.  
    .must(QueryBuilders.termQuery("field1", "value1"))
  3.  
    .mustNot(QueryBuilders.termQuery("field2", "value2"))
  4.  
    .should(QueryBuilders.termQuery("field3", "value3"))
  5.  
    .filter(QueryBuilders.termQuery("field4", "value4"));
  6.  
     
  7.  
    // 将boolQuery用于搜索请求
  8.  
    SearchRequest searchRequest = new SearchRequest("indexName");
  9.  
    searchRequest.source(new SearchSourceBuilder().query(boolQuery));

RestHighLevelClient中的matchQuery与matchPhraseQuery与termQuery的在实际使用中的不同

1. matchQuery:  
The matchQuery is a full-text query that analyzes the provided text and generates a query that performs a full-text search on the analyzed text. It is useful when you want to perform a search based on relevance. The matchQuery analyzes the text and generates a set of terms that are used for matching.

翻译:

1.匹配查询:
matchQuery是一个全文查询,用于分析所提供的文本,并生成一个对所分析的文本执行全文搜索的查询。当您想要根据相关性执行搜索时,它非常有用。matchQuery分析文本并生成一组用于匹配的术语。

2. matchPhraseQuery: 
The matchPhraseQuery is similar to the matchQuery, but it analyzes the text as a phrase rather than individual terms. It is useful when you want to search for an exact phrase in the text. The matchPhraseQuery considers the order of the terms and their proximity to each other. 

2.匹配短语查询:
matchPhraseQuery类似于matchQuery,但它将文本作为短语而不是单个术语进行分析。当你想在文本中搜索一个确切的短语时,它很有用。matchPhraseQuery考虑术语的顺序及其彼此之间的接近程度。

termQuery: The termQuery is a query that searches for exact terms in a field. It does not analyze the text and is suitable for searching on keyword fields or fields that are not analyzed. The termQuery matches documents that contain an exact term.

术语查询:
termQuery是一个在字段中搜索精确术语的查询。它不分析文本,适用于搜索关键字字段或未分析的字段。termQuery匹配包含确切术语的文档。

总结:

matchQuery和matchPhraseQuery用于全文搜索并考虑相关性,而termQuery用于精确的术语匹配,不对文本执行分析。您可以根据特定的搜索要求选择适当的查询类型。

ok,

所以简单的来说,

如果搜随机的话请使用matchQuery来完成模糊匹配,

搜索模糊的关键词使用matchPhraseQuery

对指定字段进行精确的分词搜索,适用于关键词精确搜索。

ES是否能在类型为text的字段的内部使用keyword,如果能这样做的含义是什么?

在Elasticsearch中,你可以在类型为"text"的字段内部使用"keyword"。

这种使用方式被称为"multi-fields"(多字段),它允许你在同一个字段上定义多个不同类型的子字段。
 当你在类型为"text"的字段上同时定义一个"keyword"子字段时,它的含义是:
1. "text"类型子字段:该子字段会对文本进行分析,将其拆分为单个词项,并应用分词器和过滤器等分析器组件。这样可以支持全文搜索和相关性评分。
2. "keyword"类型子字段:该子字段会将整个文本作为一个项进行索引和搜索,不进行分词和分析。这样可以实现精确匹配、排序和聚合操作。
 这种使用方式的好处是,你可以在同一个字段上同时支持全文搜索和精确匹配操作,而无需额外定义多个字段。例如,你可以使用"text"类型子字段进行全文搜索,并使用"keyword"类型子字段进行精确匹配或排序。
 以下是一个示例,展示如何在Elasticsearch中定义一个包含"text"和"keyword"子字段的字段:
json
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
在上面的示例中,"title"字段被定义为"text"类型,并包含一个名为"keyword"的"keyword"类型子字段。这样,你可以同时在"title"字段上进行全文搜索和精确匹配操作。
 总而言之,你可以在类型为"text"的字段内部使用"keyword"子字段,以实现同时支持全文搜索和精确匹配的功能。

实战:

字段

  1.  
    "agent_name": {
  2.  
    "type": "text",
  3.  
    "fields": {
  4.  
    "keyword": {
  5.  
    "ignore_above": 256,
  6.  
    "type": "keyword"
  7.  
    }
  8.  
    }
  9.  
    },

要求精准匹配到agent_name为河南神龙公司的所有信息。

  1.  
    // 指定索引
  2.  
    request.indices("smsp_collect_info_new");
  3.  
    // 构建查询条件
  4.  
    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
  5.  
    // 使用精准分词 查找
  6.  
    searchSourceBuilder.query(QueryBuilders.termQuery("agent_name.keyword", "河南神龙公司"));
  7.  
    //放入文档中
  8.  
    request.source(searchSourceBuilder);
  9.  
    //远程查询
  10.  
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  11.  
    //获取结果
  12.  
    SearchHit[] searchHits = response.getHits().getHits();
  13.  
    for (SearchHit hit : searchHits) {
  14.  
    System.out.println(hit.getSourceAsMap().get("agent_name"));
  15.  
    }
学新通

这里的agent_name字段就是运用了多字段的思想/方式。

什么是ES多字段?

ES多字段(Multi-fields)是Elasticsearch中的一个概念,它允许在一个字段上定义多个不同类型的子字段。每个子字段可以根据不同的需求进行不同的处理和索引,以便在搜索和聚合时提供更灵活的功能。
 使用多字段的主要目的是在同一个字段上同时支持多种查询需求。例如,你可能想要在一个字段上进行全文搜索、精确匹配和排序等操作。通过使用多字段,你可以根据不同的查询需求定义不同类型的子字段,从而在每个子字段上使用适当的查询方式。
 多字段可以在映射(mapping)中定义。以下是一个示例,展示如何在Elasticsearch中定义一个包含多字段的字段:
json
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          },
          "english": {
            "type": "text",
            "analyzer": "english"
          }
        }
      }
    }
  }
}
在上面的示例中,"title"字段被定义为"text"类型,并包含两个子字段:"keyword"和"english"。其中,"keyword"子字段是"keyword"类型,用于精确匹配和排序,而"english"子字段是"text"类型,并使用英文分析器进行全文搜索。
 通过使用多字段,你可以根据不同的查询需求选择适当的子字段进行搜索、排序和聚合,从而提供更灵活和准确的搜索体验。
 总而言之,ES多字段是在一个字段上定义多个不同类型的子字段,用于在不同的查询需求下提供灵活的搜索和聚合功能。

ES怎么实现聚合查询?

主要是通过AggregationBuilders来进行聚合条件的构建,然后通过aggregation方法将AggregationBuilders拼接到SearchSourceBuilder 中实现的。如果有子聚合是通过subaggregation方法进行拼装的。

聚合查询的类型

- Range Aggregation:按指定的范围对字段进行聚合,比如按价格范围聚合商品。

- Date Histogram Aggregation:按指定的时间间隔对日期字段进行聚合,比如按月份聚合销售数据。

- Histogram Aggregation:按指定的数值间隔对数值字段进行聚合,比如按价格区间聚合商品。

- Terms Aggregation:对字段进行词条聚合,类似于SQL中的GROUP BY操作。

- Avg Aggregation:计算字段的平均值。

- Sum Aggregation:计算字段的总和。

- Max Aggregation:计算字段的最大值。

- Min Aggregation:计算字段的最小值。

- Cardinality Aggregation:计算字段的基数(不重复值的数量)。

查询 分组聚合实战

  1.  
    public void GroupSearch() throws IOException {
  2.  
    SearchRequest request = new SearchRequest();
  3.  
     
  4.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  5.  
    request.indices("smsp_collect_info_new");
  6.  
    // 模糊分词查询
  7.  
    searchSourceBuilder.query(QueryBuilders.matchQuery("province", "河南"));
  8.  
    // 分组聚合查询
  9.  
    searchSourceBuilder.aggregation(AggregationBuilders
  10.  
    .terms("your_agg_name")
  11.  
    .field("agent_name.keyword")
  12.  
    .subAggregation(AggregationBuilders.count("count_number")
  13.  
    // 指定返回的桶的最大数量为10000
  14.  
    .field("company.keyword")).size(10000));
  15.  
     
  16.  
    //放入文档中
  17.  
    request.source(searchSourceBuilder);
  18.  
    //远程查询
  19.  
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  20.  
    // 获取所有的桶
  21.  
    Terms termsAggregation = response.getAggregations().get("your_agg_name");
  22.  
    for (Terms.Bucket bucket : termsAggregation.getBuckets()) {
  23.  
    // 获得每次聚合的key的值
  24.  
    System.out.println("当前的key为:" bucket.getKeyAsString());
  25.  
    ValueCount countAggregation =bucket.getAggregations().get("count_number");
  26.  
    System.out.println("当前键下的聚合属性的总和," countAggregation.getValue());
  27.  
    }
  28.  
    }
学新通

RestHighLevelClient的subAggregation是什么?干什么用的?

RestHighLevelClient的subAggregation是用于在Elasticsearch中进行嵌套聚合操作的功能。在Elasticsearch中,聚合是一种用于对数据进行分组、过滤和计算的功能,可以根据不同的聚合类型对字段进行统计、计算平均值、求和等操作。

subAggregation允许在一个聚合操作的结果上进行进一步的嵌套聚合操作。

通过使用subAggregation,可以对聚合结果进行更细粒度的分析和处理。

例如,可以在terms聚合的结果上进行子聚合,对每个聚合桶进行更深入的统计。

以下是一个使用RestHighLevelClient进行subAggregation的示例代码:

  1.  
    RestHighLevelClient client = new RestHighLevelClient(
  2.  
    RestClient.builder(new HttpHost("localhost", 9200, "http")));
  3.  
    SearchRequest searchRequest = new SearchRequest("your_index_name"); // 替换为实际的索引名
  4.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  5.  
    // 添加主聚合
  6.  
    TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("my_terms_agg")
  7.  
    .field("your_field_name"); // 替换为实际的字段名
  8.  
    // 添加子聚合
  9.  
    MaxAggregationBuilder subAggregationBuilder = AggregationBuilders.max("my_max_agg")
  10.  
    .field("your_nested_field_name"); // 替换为实际的嵌套字段名
  11.  
    aggregationBuilder.subAggregation(subAggregationBuilder);
  12.  
    searchSourceBuilder.aggregation(aggregationBuilder);
  13.  
    searchRequest.source(searchSourceBuilder);
  14.  
    try {
  15.  
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  16.  
    // 解析聚合结果
  17.  
    Terms termsAggregation = searchResponse.getAggregations().get("my_terms_agg");
  18.  
    for (Terms.Bucket bucket : termsAggregation.getBuckets()) {
  19.  
    String key = bucket.getKeyAsString();
  20.  
    Max maxAggregation = bucket.getAggregations().get("my_max_agg");
  21.  
    double max = maxAggregation.getValue();
  22.  
    // 处理聚合结果
  23.  
    System.out.println("Bucket Key: " key);
  24.  
    System.out.println("Max Value: " max);
  25.  
    }
  26.  
    } catch (IOException e) {
  27.  
    e.printStackTrace();
  28.  
    }
  29.  
    client.close();
学新通

什么是RestHighLevelClient的滚动查询?如何实现?

RestHighLevelClient的滚动查询是一种用于在Elasticsearch中检索大量数据的机制。它允许您通过多个请求迭代地获取结果集,而不是一次性获取所有结果。滚动查询适用于需要处理大量数据的情况,例如导出数据、数据分析等。
 与其他查询方式相比,滚动查询具有以下优势:
1. 可以处理大量数据:滚动查询适用于处理超过单个请求的结果集大小限制的情况。它允许您按需获取数据,而不会因为数据量过大而导致请求失败或性能下降。
2. 节省内存:滚动查询通过每次返回一小批结果并在服务器端维护滚动上下文来减少内存消耗。这使得在处理大量数据时,不需要将所有结果加载到内存中,从而节省了内存资源。
3. 支持持续查询:滚动查询的结果可以被持续使用,即使在处理期间索引中的数据发生了变化。您可以使用滚动上下文来保持查询的一致性,而不受索引更新的影响。
4. 支持并发处理:通过使用滚动查询,您可以并发地处理多个滚动上下文,从而提高查询的吞吐量和效率。
 需要注意的是,滚动查询也有一些限制和注意事项:
1. 滚动查询会占用服务器资源:由于滚动上下文需要在服务器端维护,因此会占用一定的内存和计算资源。在设计滚动查询时,需要考虑服务器的可用资源以及查询的并发性能。
2. 滚动查询的结果可能不是实时的:如果在滚动查询期间索引中的数据发生了变化,滚动查询的结果可能不会反映最新的数据。因此,在滚动查询中处理数据时,需要注意数据的一致性和实时性。
 总之,RestHighLevelClient的滚动查询是一种强大的机制,可以高效地处理大量数据。它提供了灵活的分批获取结果的方式,适用于需要处理大数据量的场景。

实现:

  1.  
    public void ScrollSearch() throws IOException {
  2.  
    SearchRequest request = new SearchRequest();
  3.  
    //失效时间为10min
  4.  
    Scroll scroll = new Scroll(TimeValue.timeValueMinutes(10));
  5.  
    //封存快照
  6.  
    request.scroll(scroll);
  7.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  8.  
    request.indices("smsp_collect_info_new");
  9.  
    searchSourceBuilder.query(QueryBuilders.matchQuery("province", "黑龙江"));
  10.  
    // 每次查询2000个,是滚动查询条数的步长
  11.  
    searchSourceBuilder.size(2000);
  12.  
    //放入文档中
  13.  
    request.source(searchSourceBuilder);
  14.  
    //远程查询
  15.  
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  16.  
    SearchHit[] searchHits = response.getHits().getHits();
  17.  
    //处理第一次的响应结果
  18.  
    for (SearchHit hit : searchHits) {
  19.  
    String province = hit.getSourceAsMap().get("province").toString();
  20.  
    System.out.println(province);
  21.  
    // 处理每个查询结果
  22.  
    }
  23.  
    // 获取第一次的滚动id
  24.  
    String scrollId = response.getScrollId();
  25.  
    while (searchHits.length > 0) {
  26.  
    // 每循环一次构建一个新的滚动请求。
  27.  
    SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
  28.  
    scrollRequest.scroll(TimeValue.timeValueMinutes(1));
  29.  
    response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
  30.  
    // 获取新的滚动请求的滚动id
  31.  
    scrollId = response.getScrollId();
  32.  
    searchHits = response.getHits().getHits();
  33.  
    // 处理下一批查询结果
  34.  
    for (SearchHit hit : searchHits) {
  35.  
    String province = hit.getSourceAsMap().get("province").toString();
  36.  
    System.out.println(province);
  37.  
    // 处理每个查询结果
  38.  
    }
  39.  
    }
  40.  
     
  41.  
    }
学新通

精确条件查询

对应的原生查询语句

注意这里的term就是精准查询到 关键字

  1.  
    GET user/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "term": {
  5.  
    "city": "上海"
  6.  
    }
  7.  
     
  8.  
    }
  9.  
    }

服务层 

  1.  
    // 文档搜索
  2.  
    public String searchDocument(String indexName,String city){
  3.  
    //2 构建搜索请求
  4.  
    SearchRequest searchRequest = new SearchRequest().indices(indexName);
  5.  
    //3 构建搜索内容
  6.  
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", city);
  7.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  8.  
    searchSourceBuilder.query(termQueryBuilder);
  9.  
    //4 填充搜索内容
  10.  
    searchRequest.source(searchSourceBuilder);
  11.  
    SearchResponse searchResponse = null;
  12.  
    try {
  13.  
    //5 执行搜索操作
  14.  
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  15.  
    } catch (IOException e) {
  16.  
    throw new RuntimeException(e);
  17.  
    }
  18.  
    //6 返回值
  19.  
    return JSON.toJSONString(searchResponse.getHits().getHits());
  20.  
    }
学新通

控制器

  1.  
     
  2.  
    @GetMapping("/searchUserByCity")
  3.  
    public String searchUserByCity() throws IOException {
  4.  
    return service.searchDocument("user","上海");
  5.  
    }

访问链接localhost:8080/searchUserByCity

学新通

分页 精确条件查询

  1.  
    GET user/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "term": {
  5.  
    "city": "上海"
  6.  
    }
  7.  
     
  8.  
    },
  9.  
    "from":0,
  10.  
    "size":5
  11.  
    }

服务层

  1.  
    // 文档搜索--分页查询
  2.  
    public String searchDocument2(String indexName,String city){
  3.  
    //2 构建搜索请求
  4.  
    SearchRequest searchRequest = new SearchRequest().indices(indexName);
  5.  
    //3 构建搜索内容
  6.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  7.  
    //拿到前5条数据
  8.  
    searchSourceBuilder
  9.  
    .query(QueryBuilders.termQuery("city", city))
  10.  
    .from(0)
  11.  
    .size(5);
  12.  
     
  13.  
    //4 填充搜索内容
  14.  
    searchRequest.source(searchSourceBuilder);
  15.  
    SearchResponse searchResponse = null;
  16.  
    try {
  17.  
    //5 执行搜索操作
  18.  
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  19.  
    } catch (IOException e) {
  20.  
    throw new RuntimeException(e);
  21.  
    }
  22.  
    //6 返回值
  23.  
    return JSON.toJSONString(searchResponse.getHits().getHits());
  24.  
    }
学新通

控制层 

  1.  
    @GetMapping("/searchUserByCity2")
  2.  
    public String searchUserByCity2() throws IOException {
  3.  
    return service.searchDocument2("user","上海");
  4.  
    }

访问localhost:8080/searchUserByCity2

字符匹配条件 精准条件查询

term 与matchphrase的比较 term用于精确查找有点像 mysql里面的"=" match是先将查询关键字分词然后再进行查找。term一般用在keywokrd类型的字段上进行精确查找。

注意这里的bool,表示使用布尔查询,其中的must是相当于SQL语句中的and的意思。

所以就是查找name中包含“妲己”并且年龄为22岁的信息,请注意不能写成"妲",因为我们在新建文档的时候是这样新建的“妲己”,那么我们如果匹配“妲”就会匹配不到,加入这样写就可以匹配到了“妲 己”,请注意空格,这是分词的依据之一

ES查询语句。

学新通

  1.  
    GET user/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool":{
  5.  
    "must": [
  6.  
    {
  7.  
    "match_phrase": {
  8.  
    "name": "妲己"
  9.  
    }
  10.  
    },
  11.  
    {
  12.  
    "term": {
  13.  
    "age": "32"
  14.  
    }
  15.  
    }
  16.  
    ]
  17.  
    }
  18.  
     
  19.  
    },
  20.  
    "from":0,
  21.  
    "size":10
  22.  
    }
学新通

服务层

  1.  
    // 文档分词搜索 精确查询
  2.  
    public String searchDocument3(String indexName,String name,Integer age){
  3.  
    //2 构建搜索请求
  4.  
    SearchRequest searchRequest = new SearchRequest().indices(indexName);
  5.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  6.  
    //3 构建复杂的查询语句
  7.  
    BoolQueryBuilder bq=QueryBuilders
  8.  
    .boolQuery()
  9.  
    //分词匹配
  10.  
    .must(QueryBuilders.matchPhraseQuery("name",name))
  11.  
    //精确匹配
  12.  
    .must(QueryBuilders.matchQuery("age",age));
  13.  
    //4 填充搜索语句
  14.  
    searchSourceBuilder
  15.  
    .query(bq)
  16.  
    .from(0)
  17.  
    .size(5);
  18.  
     
  19.  
    //4 填充搜索内容
  20.  
    searchRequest.source(searchSourceBuilder);
  21.  
    SearchResponse searchResponse = null;
  22.  
    try {
  23.  
    //5 执行搜索操作
  24.  
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  25.  
    } catch (IOException e) {
  26.  
    throw new RuntimeException(e);
  27.  
    }
  28.  
    //6 返回值
  29.  
    return JSON.toJSONString(searchResponse.getHits());
  30.  
    }
学新通

控制层

  1.  
    @GetMapping("/searchUser3")
  2.  
    public String searchUser3() throws IOException {
  3.  
    return service.searchDocument3("user","妲己",32);
  4.  
    }

学新通字符匹配OR精准查询

 原始查询语句

  1.  
    GET user/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool":{
  5.  
    "should": [
  6.  
    {
  7.  
    "match_phrase": {
  8.  
    "name": "妲己"
  9.  
    }
  10.  
    },
  11.  
    {
  12.  
    "term": {
  13.  
    "age": "32"
  14.  
    }
  15.  
    }
  16.  
    ]
  17.  
    }
  18.  
     
  19.  
    },
  20.  
    "from":0,
  21.  
    "size":10
  22.  
    }
学新通

服务层

  1.  
    // 文档分词搜索OR精确查询
  2.  
    public String searchDocument4(String indexName,String name,Integer age){
  3.  
    //2 构建搜索请求
  4.  
    SearchRequest searchRequest = new SearchRequest().indices(indexName);
  5.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  6.  
    //3 构建复杂的查询语句
  7.  
    BoolQueryBuilder bq=QueryBuilders
  8.  
    .boolQuery()
  9.  
    //分词匹配
  10.  
    .should(QueryBuilders.matchPhraseQuery("name",name))
  11.  
    //精确匹配
  12.  
    .should(QueryBuilders.matchQuery("age",age));
  13.  
    //4 填充搜索语句
  14.  
    searchSourceBuilder
  15.  
    .query(bq)
  16.  
    .from(0)
  17.  
    .size(5);
  18.  
     
  19.  
    //4 填充搜索内容
  20.  
    searchRequest.source(searchSourceBuilder);
  21.  
    SearchResponse searchResponse = null;
  22.  
    try {
  23.  
    //5 执行搜索操作
  24.  
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  25.  
    } catch (IOException e) {
  26.  
    throw new RuntimeException(e);
  27.  
    }
  28.  
    //6 返回值
  29.  
    return JSON.toJSONString(searchResponse.getHits());
  30.  
    }
学新通

控制层 

  1.  
    @GetMapping("/searchUser4")
  2.  
    public String searchUser4() throws IOException {
  3.  
    return service.searchDocument4("user","妲己",22);
  4.  
    }

 结果

学新通

模糊查询

原始语句

  1.  
    GET user/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "wildcard": {
  5.  
    "city": {
  6.  
    "value": "上*"
  7.  
    }
  8.  
    }
  9.  
    }
  10.  
    }
  1.  
    // 文档模糊查询
  2.  
    public String searchDocument5(String indexName,String city){
  3.  
    //2 构建搜索请求
  4.  
    SearchRequest searchRequest = new SearchRequest().indices(indexName);
  5.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  6.  
    //3 构建模糊查询的语句
  7.  
    WildcardQueryBuilder bq=QueryBuilders
  8.  
    .wildcardQuery("city",city);
  9.  
    //4 填充搜索语句
  10.  
    searchSourceBuilder
  11.  
    .query(bq);
  12.  
     
  13.  
    searchRequest.source(searchSourceBuilder);
  14.  
    SearchResponse searchResponse = null;
  15.  
    try {
  16.  
    //5 执行搜索操作
  17.  
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  18.  
    } catch (IOException e) {
  19.  
    throw new RuntimeException(e);
  20.  
    }
  21.  
    //6 返回值
  22.  
    return JSON.toJSONString(searchResponse.getHits());
  23.  
    }
学新通
  1.  
    @GetMapping("/searchUser5")
  2.  
    public String searchUser5() throws IOException {
  3.  
    return service.searchDocument5("user","上*");
  4.  
    }

结果 

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanheiigba
系列文章
更多 icon
同类精品
更多 icon
继续加载