Springboot 集成 elasticsearch 之索引,映射,文档查询 ,过滤查询,聚合查询

集成Springboot

导入pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

ES 的核心概念

索引

一个索引就是一个拥有几分相似特征的文档集合,比如说,你可以有一个商品数据的索引,一个订单数据索引,还有一个用户数据的索引,一个索引有一个名字来标识(ps:必须是小写字母全部)并且当我们要对这个索引中的文档进行索引,搜索,更新和删除的时候都要用这个名字。

映射

映射是定义一个文档和它所在包含的字段如何被储存和索引的过程
,在默认配置下 ES 可以根据插入的数据自动创建mapping 也可以手动创建mapping mapping 中主要包括字段名,字段类型等

文档

文档是索引中存储的一条条数据,一条文档是一个可被索引的最小单元,ES 中的文档采用了轻量级的JSON 格式数据来表示。

使用 RestHighLevelClient

创建elasticsearchConfig

@Configuration
public class SpringbootConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200,"http"))
        );
        return client;
    }
}

索引操作 (CRUD)

 @Autowired
    @Qualifier("restHighLevelClient")
    RestHighLevelClient client;
    // 创建索引
    @Test
    void CreateIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("fengjioajaio");
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);

    }

    // 获取索引
    @Test
    void GetIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("fengjioajaio");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    // 删除索引
    @Test
    void DeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("fengjioajaio");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(delete);

    }

文档操作 (CRUD)

 // 添加文档
    @Test
    void AddDoc() throws IOException {
        User user = new User("娇娇", "123456", "^(* ̄(oo) ̄)^");
        // 创建要添加的索引
        IndexRequest request = new IndexRequest("fengjioajaio");
        // 添加 id 等
        request.id("1").timeout("1s").timeout(TimeValue.timeValueSeconds(1)).source(JSON.toJSONString(user), XContentType.JSON);
        // 发送客户端
        IndexResponse index = client.index(request, RequestOptions.DEFAULT);
        System.out.println(index.status());
        System.out.println(index.toString());
    }
    // 获取文档
    @Test
    void GetDoc() throws IOException {
        GetRequest request = new GetRequest("fengjioajaio","1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString()); // 打印文档的内容
        System.out.println(response);
    }
    // 更新文档
    @Test
    void UpdateDoc() throws IOException {
        UpdateRequest request = new UpdateRequest("fengjioajaio", "1");
        User user = new User("我是美女", "23444", "fjrkfkggre");
        request.id("1").timeout("1s").doc(JSON.toJSONString(user),XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        System.out.println(update);
        System.out.println(request);

    }
    // 删除文档
    @Test
    void DeleteDoc() throws IOException {
        DeleteRequest request = new DeleteRequest("fengjioajaio");
        request.id("1");
        DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete);
    }
    // 批量插入数据
    @Test
    void BuckAdd(List<?> list,String IndexName) throws IOException {
        BulkRequest request = new BulkRequest();
        list.forEach(s -> {
            request.timeout("10s").add(new IndexRequest(IndexName).source(JSON.toJSONString(s),XContentType.JSON));
        });
        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println("bulk = " + bulk);
    }
    

文档查询 花式查询

查询全部

    @Test
    // 查询全部
    public void queryAll() throws IOException {
        // 这里可以添加多个索引的名字 indixes 是加了s 的是可以添加多个 索引给他 查询的请求
        SearchRequest request = new SearchRequest(INDEX_NAME);
        // 创建构造器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 添加搜索的条件
        builder.query(QueryBuilders.matchAllQuery());
        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 总条数
        System.out.println("总条数"+response.getHits().getTotalHits().value);
        // 最大分数
        System.out.println("最大分数"+response.getHits().getMaxScore());
        // 查询时间
        System.out.println("查询时间"+response.getTook());
        // 拿到我们的数据
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println("id 是" +s.getId());
            // 具体数据
            System.out.println("具体数据"+s.getSourceAsString());
        });

    }

这里需要注意一下 ES 在不设置分页的时候默认是出来10条数据
在这里插入图片描述要是想查看全部数据的话 可以 设置分页 这样就可以显示多个数据了。

关键字查询

        SearchRequest request = new SearchRequest(INDEX_NAME);
        // 创建构造器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 添加条件  adress 是你的字段名 后面的是你要查询什么
        builder.query(QueryBuilders.termQuery("address","安"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        // 总条数
        System.out.println("总条数"+response.getHits().getTotalHits().value);
        // 最大分数
        System.out.println("最大分数"+response.getHits().getMaxScore());
        // 查询时间
        System.out.println("查询时间"+response.getTook());
        // 拿到我们的数据
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println("id 是" +s.getId());
            // 具体数据
            System.out.println("具体数据"+s.getSourceAsString());
        });

这里代码有点冗余,我把关键的代码抽离出来了

  // 抽离出来的查询的方法
    public void query (QueryBuilder queryBuilder) throws IOException{
        // 创建 请求
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(queryBuilder);
        request.source(builder);
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 总条数
        System.out.println("总条数"+response.getHits().getTotalHits().value);
        // 最大分数
        System.out.println("最大分数"+response.getHits().getMaxScore());
        // 查询时间
        System.out.println("查询时间"+response.getTook());
        // 拿到我们的数据
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println("id 是" +s.getId());
            // 具体数据
            System.out.println("具体数据"+s.getSourceAsString());
        });
    }

尝试 代码少了很多冗余的

    // 关键词查询
    @Test
    public void queryLike() throws IOException {
        query(QueryBuilders.termQuery("address","南"));
    }

范围查询

   // range 查询
    @Test
    public void queryRange() throws IOException{
        query(QueryBuilders.rangeQuery("id").gt(1).lte(20));
    }

前缀查询

    // 前缀查询
    @Test
    public void queryPrefix() throws IOException {
        query(QueryBuilders.prefixQuery("address","贵州省"));
    }

通配符查询

    @Test
    public void queryDemo() throws IOException {
        // 通配符查询 ? 表示一个字符 * 任意多个字符
        query(QueryBuilders.wildcardQuery("address","贵州省*"));
    }

ids 多个指定的 id查询

    @Test
    public void queryDemo() throws IOException {
        // ids 多个指定 id 查询
        query(QueryBuilders.idsQuery().addIds("1"));
    }

多字段查询

    @Test
    public void queryDemo() throws IOException {
    // multi_match 多字段查询
        query(QueryBuilders.multiMatchQuery("贵州省","address","title"));
    }

模糊查询

    @Test
    public void queryDemo() throws IOException {
        query(QueryBuilders.fuzzyQuery("address","贵州省"));
    }

这里要注意

  1. 搜索关键词长度为2 不允许存在模糊
  2. 搜索关键词为3-5 允许一次模糊
  3. 搜索关键词长度大于5允许最大的模糊

布尔查询

    @Test
    public void queryDemo() throws IOException {
        query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("address","贵州省")).must(QueryBuilders.idsQuery().addIds("1")));
    }
  1. bool 关键字用来组合多个条件实现复杂查询
  2. must :相当于 && 同时成立
  3. should 相当于 || 成立一个就行
  4. must_not :相当于!不能满足任何一个

默认字段分词查询

    @Test
    public void queryDemo() throws IOException {
       query(QueryBuilders.queryStringQuery("address").queryName("贵州省"));
    }

返回指定字段

    @Test
    public void querySize() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        //1, 包含字段的数组 2 排除字段数组
        builder.fetchSource(new String[]{"address"},new String[]{});
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println(s.getSourceAsString());
        });
    }

分页查询

    @Test
    public void querySize() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 每页显示的条数
        builder.size(2);
        // 起始字段
        builder.from(0);
        builder.query(QueryBuilders.matchAllQuery());
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println(s.getSourceAsString());
        });
    }

排序

    @Test
    public void querySize() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        
        builder.query(QueryBuilders.matchAllQuery());
        // 第一个字段是你要通过那个字段来进行排序 第二个参数 你要如何排序
        builder.sort("id", SortOrder.DESC);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println(s.getSourceAsString());
        });
    }

高亮查询

      @Test
    public void querySize() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.termQuery("贵州","address"));
        // 创建高亮器
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false).field("address");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            Map<String, HighlightField> map = s.getHighlightFields();
            if (map.containsKey("address")) {
                System.out.println("map.get(\"address\").fragments()[0] = " + map.get("address").fragments()[0]);
            }
        });
    }

过滤查询

过滤查询

    @Test
    // 查询全部
    public void queryAll() throws IOException {
        // 这里可以添加多个索引的名字 indixes 是加了s 的是可以添加多个 索引给他 查询的请求
        SearchRequest request = new SearchRequest(INDEX_NAME);
        // 创建构造器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 添加搜索的条件  如果同时使用过滤跟query 的话优先是执行的 过滤的
   builder.query(QueryBuilders.matchAllQuery()).postFilter(QueryBuilders.termQuery("address","贵州省"));
        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 总条数
        System.out.println("总条数"+response.getHits().getTotalHits().value);
        // 最大分数
        System.out.println("最大分数"+response.getHits().getMaxScore());
        // 查询时间
        System.out.println("查询时间"+response.getTook());
        // 拿到我们的数据
        SearchHit[] hits = response.getHits().getHits();
        Arrays.stream(hits).forEach(s->{
            System.out.println("id 是" +s.getId());
            // 具体数据
            System.out.println("具体数据"+s.getSourceAsString());
        });

    }

聚合查询

聚合是ES除搜索功能外提供的针对es 数据做统计分析的功能。聚合有助于根据搜索查询提供聚合数据。聚合查询是数据库中重要的功能特效,ES 作为搜索引擎兼数据库 同样提供了强大的聚合分析能力 它基于查询条件来对数据进行分桶,计算的方法 有点类似于SQL 中的 group by 再加一些函数方法的操作。

根据某个字段分组

    @Test
    public void queryAggs() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery())
        .aggregation(AggregationBuilders.terms("contractTerm_group").field("contractTerm")) // 设置聚合操作
        .size(0)
        ; // 查询条件
        request.source(searchSourceBuilder);
        // 客户端发送消息
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Aggregations aggregations = response.getAggregations();
        ParsedDoubleTerms aggregation = aggregations.get("contractTerm_group");
        List<? extends Terms.Bucket> list = aggregation.getBuckets();
        list.stream().forEach(s->{
            System.out.println(s.getKey());
            System.out.println(s.getDocCount());
        });

    }

求最大值

  @Test
    public void queryMax() throws IOException{
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery())
                .aggregation(AggregationBuilders.max("contractTerm_max").field("contractTerm"));
        request.source(builder);
        // 客户端发送消息
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 打印数据
        Aggregations aggregations = response.getAggregations();
        ParsedMax aggregation = aggregations.get("contractTerm_max");
        double value = aggregation.getValue();
        System.out.println(
                value
        );

    }

最小值

    @Test
    public void queryMax() throws IOException{
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery())
                .aggregation(AggregationBuilders.min("contractTerm_min").field("contractTerm"));
        request.source(builder);
        // 客户端发送消息
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 打印数据
        Aggregations aggregations = response.getAggregations();
        ParsedMin aggregation = aggregations.get("contractTerm_min");
        double value = aggregation.getValue();
        System.out.println(
                value
        );

    }

平均值

    // 求平均值
    @Test
    public void queryAvg() throws IOException {
        SearchRequest request = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery())
        .aggregation(AggregationBuilders.avg("contractTerm_avg").field("contractTerm"))

        ;
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Aggregations aggregations = response.getAggregations();
        ParsedAvg contractTerm = aggregations.get("contractTerm_avg");
        System.out.println(contractTerm.getValue());
    }
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答一下关于如何在Spring Boot中集成Elasticsearch的问题。 首先,你需要确保你的Spring Boot项目中已经引入了Spring Data Elasticsearch依赖。可以在项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 接下来,你需要配置Elasticsearch客户端连接信息。在application.properties(或者application.yml)文件中添加以下配置: ```properties spring.data.elasticsearch.cluster-nodes=<elasticsearch服务器地址>:<端口号> ``` 配置完毕后,你可以在Spring Boot应用中使用Elasticsearch的Repository接口来访问Elasticsearch。 例如,创建一个Book实体类: ```java @Document(indexName = "book") public class Book { @Id private String id; private String name; private String author; private String description; // 省略getter和setter方法 } ``` 然后创建一个继承自ElasticsearchRepository的BookRepository接口: ```java public interface BookRepository extends ElasticsearchRepository<Book, String> { List<Book> findByName(String name); } ``` 在这个接口中,我们定义了一个根据书名查询书籍的方法。在使用时,可以直接注入这个接口,并调用其中的方法: ```java @Service public class BookService { @Autowired private BookRepository bookRepository; public List<Book> searchBooks(String name) { return bookRepository.findByName(name); } } ``` 以上就是在Spring Boot中集成Elasticsearch的基本步骤。希望可以对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值