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

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

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

导入pom.xml

        
            org.springframework.boot
            spring-boot-starter-data-elasticsearch
        
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 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 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());
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5698670.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存