Elasticsearch 学习+SpringBoot实战教程(三)

这篇具有很好参考价值的文章主要介绍了Elasticsearch 学习+SpringBoot实战教程(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

Elasticsearch 学习+SpringBoot实战教程(一)

Elasticsearch 学习+SpringBoot实战教程(一)_桂亭亭的博客-CSDN博客

Elasticsearch 学习+SpringBoot实战教程(二)  

Elasticsearch 学习+SpringBoot实战教程(二)_桂亭亭的博客-CSDN博客

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

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

同时需要给规范化操作

目录

0 前辈动作

1 Springboot项目引入依赖

2 建立目录与文件

3 配置文件

 4 实体类

1 使用ElasticsearchOperations的方式

新增文档

更新文档 

删除文档

查询所有

查询指定id

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

2 使用RestHighLevelClient的方式

精确查询

分页查询

字符匹配AND精准查询

​编辑字符匹配OR精准查询

模糊查询


0 前置动作

1 Springboot项目引入依赖

注意你的ES版本号

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.20</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.10.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.10.1</version>
        </dependency>

2 建立目录与文件

Elasticsearch 学习+SpringBoot实战教程(三)

 Elasticsearch 学习+SpringBoot实战教程(三)

Elasticsearch 学习+SpringBoot实战教程(三)

Elasticsearch 学习+SpringBoot实战教程(三)

3 配置文件

Elasticsearch 学习+SpringBoot实战教程(三)

spring:
  elasticsearch:
    uris: localhost:9200
    connection-timeout: 3000
    socket-timeout: 5000

 4 实体类

package com.example.eslearn.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;

/**
 *  Document:  将这个类对象转为 es 中一条文档进行录入
 * indexName: 用来指定文档的索引名称
 * createIndex: 用来指定是否创建索引,默认为false
 */
@Document(indexName = "user", createIndex = true)
public class UserDocument implements Serializable {
    @Id // 用来将放入对象id值作为文档_id进行映射
    private String id;
    @Field(type = FieldType.Keyword)    // 字段映射类型
    private String name;
    private String sex;
    private Integer age;
    @Field(type = FieldType.Text)    // 字段映射类型

    private String city;

1 使用ElasticsearchOperations的方式

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

新增文档

    private final ElasticsearchOperations ESO;
    // set方法注入
    @Autowired
    public CRUDService2(ElasticsearchOperations elasticsearchOperations) {
        this.ESO = elasticsearchOperations;
    }
    // 新增文档
    public String save() {
        UserDocument user = new UserDocument();
        user.setName("说不定看见的");
        user.setCity("北京 上海 西安");
        user.setAge(22);
        user.setSex("男");
        UserDocument save = ESO.save(user);
        System.out.println(save);
        return JSON.toJSONString(save);
    }

Elasticsearch 学习+SpringBoot实战教程(三)

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

Elasticsearch 学习+SpringBoot实战教程(三)Elasticsearch 学习+SpringBoot实战教程(三)

更新文档 

    // 更新文档
    public String update() {
        UserDocument user = new UserDocument();
        user.setId("W7w2HYcB32f1ZLmxRwzw");
        user.setName("说快来打见的");
        user.setCity("北京 上海 西安");
        user.setAge(21);
        user.setSex("女");
        UserDocument save = ESO.save(user);
        System.out.println(save);
        return JSON.toJSONString(save);
    }

Elasticsearch 学习+SpringBoot实战教程(三)

Elasticsearch 学习+SpringBoot实战教程(三)

删除文档

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

Elasticsearch 学习+SpringBoot实战教程(三)

查询所有

    // 查询所有
    public String findAll(){
        //查询所有
        SearchHits<UserDocument> search = ESO.search(Query.findAll(), UserDocument.class);
        for (SearchHit<UserDocument> uc : search) {
            System.out.println(uc.getContent());
        }
        return JSON.toJSONString(search);
    }

Elasticsearch 学习+SpringBoot实战教程(三)

查询指定id

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

Elasticsearch 学习+SpringBoot实战教程(三)

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

服务层

 //大杂烩,一次学会
    public String findSource(){
        //查询条件构建
        MatchQueryBuilder mp=new MatchQueryBuilder("name","妲己");

        //排序构建
        FieldSortBuilder f = new FieldSortBuilder("age");
        //分页构建
        Pageable page= PageRequest.of(0,5);
        // 高亮构建
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .preTags("<span style='color:yellow'>")
                .postTags("</span>")
                .field("name");
        //结果过滤构建,相当于返回那些字段
        FetchSourceFilter filter = new FetchSourceFilter(new String[]{"name", "city"}, null);
        //查询语句构建
        NativeSearchQueryBuilder  query = new NativeSearchQueryBuilder()
                .withQuery(mp)
                .withSorts(f)
                .withPageable(page)
                .withHighlightBuilder(highlightBuilder)
                .withSourceFilter(filter);
        //执行查询
        SearchHits<UserDocument> search = ESO.search(query.build(), UserDocument.class);
        return JSON.toJSONString(search);
    }

控制器

    @GetMapping("/findSource")
    private String findSource(){
        return sv.findSource();
    }

Elasticsearch 学习+SpringBoot实战教程(三)

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 的字段

简单的复合查询

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .must(QueryBuilders.termQuery("field1", "value1"))
    .mustNot(QueryBuilders.termQuery("field2", "value2"))
    .should(QueryBuilders.termQuery("field3", "value3"))
    .filter(QueryBuilders.termQuery("field4", "value4"));

// 将boolQuery用于搜索请求
SearchRequest searchRequest = new SearchRequest("indexName");
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"子字段,以实现同时支持全文搜索和精确匹配的功能。

实战:

字段

				"agent_name": {
					"type": "text",
					"fields": {
						"keyword": {
							"ignore_above": 256,
							"type": "keyword"
						}
					}
				},

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

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

这里的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:计算字段的基数(不重复值的数量)。

查询+分组聚合实战

public void GroupSearch() throws IOException {
        SearchRequest request = new SearchRequest();

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        request.indices("smsp_collect_info_new");
        // 模糊分词查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("province", "河南"));
        // 分组聚合查询
        searchSourceBuilder.aggregation(AggregationBuilders
                .terms("your_agg_name")
                .field("agent_name.keyword")
                .subAggregation(AggregationBuilders.count("count_number")
                        // 指定返回的桶的最大数量为10000
                        .field("company.keyword")).size(10000));

        //放入文档中
        request.source(searchSourceBuilder);
        //远程查询
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 获取所有的桶
        Terms termsAggregation = response.getAggregations().get("your_agg_name");
        for (Terms.Bucket bucket : termsAggregation.getBuckets()) {
            // 获得每次聚合的key的值
            System.out.println("当前的key为:"+bucket.getKeyAsString());
            ValueCount countAggregation =bucket.getAggregations().get("count_number");
            System.out.println("当前键下的聚合属性的总和,"+countAggregation.getValue());
        }
    }

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

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

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

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

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

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

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(new HttpHost("localhost", 9200, "http")));
 SearchRequest searchRequest = new SearchRequest("your_index_name"); // 替换为实际的索引名
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
 // 添加主聚合
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("my_terms_agg")
        .field("your_field_name"); // 替换为实际的字段名
 // 添加子聚合
MaxAggregationBuilder subAggregationBuilder = AggregationBuilders.max("my_max_agg")
        .field("your_nested_field_name"); // 替换为实际的嵌套字段名
aggregationBuilder.subAggregation(subAggregationBuilder);
 searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
 try {
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
     // 解析聚合结果
    Terms termsAggregation = searchResponse.getAggregations().get("my_terms_agg");
    for (Terms.Bucket bucket : termsAggregation.getBuckets()) {
        String key = bucket.getKeyAsString();
        Max maxAggregation = bucket.getAggregations().get("my_max_agg");
        double max = maxAggregation.getValue();
         // 处理聚合结果
        System.out.println("Bucket Key: " + key);
        System.out.println("Max Value: " + max);
    }
} catch (IOException e) {
    e.printStackTrace();
}
 client.close();

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

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

实现:

public void ScrollSearch() throws IOException {
        SearchRequest request = new SearchRequest();
        //失效时间为10min
        Scroll scroll = new Scroll(TimeValue.timeValueMinutes(10));
        //封存快照
        request.scroll(scroll);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        request.indices("smsp_collect_info_new");
        searchSourceBuilder.query(QueryBuilders.matchQuery("province", "黑龙江"));
        // 每次查询2000个,是滚动查询条数的步长
        searchSourceBuilder.size(2000);
        //放入文档中
        request.source(searchSourceBuilder);
        //远程查询
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] searchHits = response.getHits().getHits();
        //处理第一次的响应结果
        for (SearchHit hit : searchHits) {
            String province = hit.getSourceAsMap().get("province").toString();
            System.out.println(province);
            // 处理每个查询结果
        }
        // 获取第一次的滚动id
        String scrollId = response.getScrollId();
        while (searchHits.length > 0) {
            // 每循环一次构建一个新的滚动请求。
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(TimeValue.timeValueMinutes(1));
            response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            // 获取新的滚动请求的滚动id
            scrollId = response.getScrollId();
            searchHits = response.getHits().getHits();
            // 处理下一批查询结果
            for (SearchHit hit : searchHits) {
                String province = hit.getSourceAsMap().get("province").toString();
                System.out.println(province);
                // 处理每个查询结果
            }
        }

    }

精确条件查询

对应的原生查询语句

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

GET user/_search
{
  "query": {
    "term": {
      "city": "上海"
    }
    
  }
}

服务层 

    // 文档搜索
    public String searchDocument(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        //3 构建搜索内容
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", city);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(termQueryBuilder);
        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits().getHits());
    }

控制器


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

访问链接localhost:8080/searchUserByCity

Elasticsearch 学习+SpringBoot实战教程(三)

分页+精确条件查询

GET user/_search
{
  "query": {
    "term": {
      "city": "上海"
    }
    
  },
  "from":0,
  "size":5
}

服务层

  // 文档搜索--分页查询
    public String searchDocument2(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        //3 构建搜索内容
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //拿到前5条数据
        searchSourceBuilder
                .query(QueryBuilders.termQuery("city", city))
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits().getHits());
    }

控制层 

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

访问localhost:8080/searchUserByCity2

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

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

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

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

ES查询语句。

Elasticsearch 学习+SpringBoot实战教程(三)

GET user/_search
{
  "query": {
    "bool":{
      "must": [
        {
          "match_phrase": {
            "name": "妲己"
          }
        },
         {
          "term": {
            "age": "32"
          }
        }
      ]
    }
    
  },
  "from":0,
  "size":10
}

服务层

// 文档分词搜索+精确查询
    public String searchDocument3(String indexName,String name,Integer age){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建复杂的查询语句
        BoolQueryBuilder bq=QueryBuilders
                .boolQuery()
                //分词匹配
                .must(QueryBuilders.matchPhraseQuery("name",name))
                //精确匹配
                .must(QueryBuilders.matchQuery("age",age));
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq)
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }

控制层

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

字符匹配OR精准查询

 原始查询语句

GET user/_search
{
  "query": {
    "bool":{
      "should": [
        {
          "match_phrase": {
            "name": "妲己"
          }
        },
         {
          "term": {
            "age": "32"
          }
        }
      ]
    }
    
  },
  "from":0,
  "size":10
}

服务层

    // 文档分词搜索OR精确查询
    public String searchDocument4(String indexName,String name,Integer age){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建复杂的查询语句
        BoolQueryBuilder bq=QueryBuilders
                .boolQuery()
                //分词匹配
                .should(QueryBuilders.matchPhraseQuery("name",name))
                //精确匹配
                .should(QueryBuilders.matchQuery("age",age));
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq)
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }

控制层 

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

 结果

Elasticsearch 学习+SpringBoot实战教程(三)

模糊查询

原始语句

GET user/_search
{
  "query": {
    "wildcard": {
      "city": {
        "value": "上*"
      }
    }
  }
}
    // 文档模糊查询
    public String searchDocument5(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建模糊查询的语句
        WildcardQueryBuilder bq=QueryBuilders
                .wildcardQuery("city",city);
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }
    @GetMapping("/searchUser5")
    public String searchUser5() throws IOException {
        return service.searchDocument5("user","上*");
    }

结果 

Elasticsearch 学习+SpringBoot实战教程(三)文章来源地址https://www.toymoban.com/news/detail-408721.html

到了这里,关于Elasticsearch 学习+SpringBoot实战教程(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java实战:SpringBoot+ElasticSearch 实现模糊查询

    本文将详细介绍如何使用SpringBoot整合ElasticSearch,实现模糊查询、批量CRUD、排序、分页和高亮功能。我们将深入探讨ElasticSearch的相关概念和技术细节,以及如何使用SpringData Elasticsearch库简化开发过程。 ElasticSearch是一个基于Lucene构建的开源搜索引擎,它提供了一个分布式、多

    2024年04月25日
    浏览(36)
  • SpringBoot集成Elasticsearch7.4 实战(一)

    在网上已经有好多关于Elasticsearch的介绍,就不在翻来覆去讲一些基本概念,大家感兴趣的可以自己去找一些资料巩固下。这次只为了顾及众多首次接触Elasticsearch,案例都讲的很浅显,还有就是受个人能力所限,各位读者发现有错误之处,也可进行讨论和指出。 本篇文章主要

    2023年04月09日
    浏览(55)
  • 【Elasticsearch】从零开始搭建ES8集群并且集成到Springboot,更好的服务电商类等需要全文索引的项目(一)

    最近公司的电商项目越来越庞大,功能需求点也越来越多,各种C端对查询和检索的要求也越来越高,是时候在项目中引入全文检索了。 ElasticSearch 是一个基于 Lucene 的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,并且是基于Java 开发的,我记得很久之前ES还不

    2024年02月15日
    浏览(48)
  • 【SpringBoot整合ElasticSearch7.x及实战】

    此笔记内容为狂神说SpringBoot整合ElasticSearch部分 目录 一、SpringBoot整合 1、创建工程 2、导入依赖 导入elasticsearch依赖 提前导入fastjson、lombok 3、创建并编写配置类 4、创建并编写实体类 5、测试 索引的操作 文档的操作 二、ElasticSearch实战 防京东商城搜索(高亮) 1、工程创建(

    2024年02月08日
    浏览(59)
  • SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)

    上一节讲述了 SpringBoot 实现 elasticsearch 索引操作,这一章节讲述 SpringBoot 实现 elasticsearch 查询操作。 案例用到的索引库结构

    2024年02月11日
    浏览(46)
  • Elasticsearch实战(五):Springboot实现Elasticsearch电商平台日志埋点与搜索热词

    Elasticsearch实战(一):Springboot实现Elasticsearch统一检索功能 Elasticsearch实战(二):Springboot实现Elasticsearch自动汉字、拼音补全,Springboot实现自动拼写纠错 Elasticsearch实战(三):Springboot实现Elasticsearch搜索推荐 Elasticsearch实战(四):Springboot实现Elasticsearch指标聚合与下钻分析

    2024年02月09日
    浏览(39)
  • Elasticsearch安装、使用,Springboot整合Elasticsearch详细教程

    Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够实现近乎实时的搜索。 Elasticsearch官网 https://www.elastic.co/cn/ 这篇文章主要简单介绍一下Elasticsearch,Elasticsearch的java API博主也在学习中,文章会持续更新~ 目录 第一步:下载Elasticsearch 下载7.6.2版本 下载其他版本

    2024年02月04日
    浏览(35)
  • 基于SpringBoot的ElasticSearch操作(超详细教程)

    ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多员工能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 语言开发的,并作为 Apache 许可条款下的开放源码发布,是一种流行的企业级搜索引擎。 ElasticSearch 用于云计算中,能够达到实时搜索,稳定

    2024年02月05日
    浏览(36)
  • elasticsearch学习入门+实战

    学习链接1 官网学习:地址 PS:使用Apifox测试 查询所有索引库 添加索引库 添加时,加入分词器 添加时,加入记录属性值 查询获取索引库 删除索引库 添加文档 必须要在添加文档值的时候用【_doc】,否则值是添加不进去的 6. 带条件的搜索[query方式的搜索] 采用json查询, a.

    2024年02月16日
    浏览(34)
  • Elasticsearch8.8.0 SpringBoot实战操作各种案例(索引操作、聚合、复杂查询、嵌套等)

    Elasticsearch8.8.0 全网最新版教程 从入门到精通 通俗易懂 引入依赖 添加配置文件 application.yaml 导入ca证书到项目中 从任意一个es容器中,拷贝证书到resources目录下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXytUrDp-1691330960034)(media/16912196423122/16

    2024年02月13日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包