前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【纯干货】SpringBoot 整合 ES 进行各种高级查询搜索

【纯干货】SpringBoot 整合 ES 进行各种高级查询搜索

作者头像
Java极客技术
发布2022-12-04 12:21:04
2.5K0
发布2022-12-04 12:21:04
举报
文章被收录于专栏:Java极客技术

一、简介

在上篇 SpringBoot 整合 ElasticSearch 文章中,我们详细的介绍了 ElasticSearch 的索引和文档的基本增删改查的操作方法!

本文将重点介绍 ES 的各种高级查询写法和使用。

废话不多说,直接上代码!

二、代码实践

本文采用的SpringBoot版本号是2.1.0.RELEASE,服务端 es 的版本号是6.8.2,客户端采用的是官方推荐的Elastic Java High Level Rest Client版本号是6.4.2,方便与SpringBoot的版本兼容。

es 最大的亮点就是查询非常丰富,可以在上亿的数据里面快速搜索出目标数据,查询如果实现呢?请看下文

  • 单条件精确查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 单条件精确查询
     * @throws IOException
     */
    @Test
    public void search0() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.termsQuery("name", "赵里"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 多条件精确查询,取并集
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 多条件精确查询,取并集
     * @throws IOException
     */
    @Test
    public void search1() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.termsQuery("name", "张", "陈"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 范围查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 范围查询,包括from、to
     * @throws IOException
     */
    @Test
    public void search2() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.rangeQuery("age").from(20).to(32));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }


    /**
     * 范围查询,不包括from、to
     * @throws IOException
     */
    @Test
    public void search3() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.rangeQuery("age").from(20,false).to(30, false));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }


    /**
     * 范围查询, lt:小于,gt:大于
     * @throws IOException
     */
    @Test
    public void search4() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.rangeQuery("age").lt(30).gt(20));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 模糊查询,支持通配符
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 模糊查询,支持通配符
     * @throws IOException
     */
    @Test
    public void search5() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.wildcardQuery("name","张三"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 不使用通配符的模糊查询,左右匹配
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 不使用通配符的模糊查询,左右匹配
     * @throws IOException
     */
    @Test
    public void search6() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.queryStringQuery("张三").field("name"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 多字段模糊查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 多字段模糊查询
     * @throws IOException
     */
    @Test
    public void search7() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.multiMatchQuery("长", "name", "city"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 多字段模糊查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 分页搜索
     * @throws IOException
     */
    @Test
    public void search8() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .from(0).size(2);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 字段排序
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 排序,字段的类型必须是:integer、double、long或者keyword
     * @throws IOException
     */
    @Test
    public void search9() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .sort("createTime", SortOrder.ASC);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 精确统计筛选文档数
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 精确统计筛选文档数,查询性能有所降低
     * @throws IOException
     */
    @Test
    public void search10() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .trackTotalHits(true);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 设置源字段过滤返回
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
     * @throws IOException
     */
    @Test
    public void search11() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .fetchSource(new String[]{"name","age","city","createTime"},new String[]{});

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • 根据 id 精确匹配
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 根据id精确匹配
     * @throws IOException
     */
    @Test
    public void search12() throws IOException {
        String[] ids = new String[]{"1","2"};
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.termsQuery("_id", ids));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }

}
  • matchAllQuery 搜索全部
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * matchAllQuery搜索全部
     * @throws IOException
     */
    @Test
    public void search21() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery());

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • match 搜索匹配
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * match搜索匹配
     * @throws IOException
     */
    @Test
    public void search22() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder()
                .query(QueryBuilders.matchQuery("name", "张王"));

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • bool组合查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * bool组合查询
     * @throws IOException
     */
    @Test
    public void search23() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
        builder.query(boolQueryBuilder);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • nested 类型嵌套查询
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * nested类型嵌套查询
     * @throws IOException
     */
    @Test
    public void search24() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件查询
        BoolQueryBuilder mainBool=new BoolQueryBuilder();
        mainBool.must(QueryBuilders.matchQuery("name", "赵六"));

        //nested类型嵌套查询
        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("products.brand", "A"));
        boolQueryBuilder.must(QueryBuilders.matchQuery("products.title", "巧克力"));
        NestedQueryBuilder nested = QueryBuilders.nestedQuery("products",boolQueryBuilder, ScoreMode.None);
        mainBool.must(nested);

        builder.query(mainBool);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • 多条件查询 + 排序 + 分页
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 多条件查询 + 排序 + 分页
     * @throws IOException
     */
    @Test
    public void search29() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件搜索
        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
        builder.query(boolQueryBuilder);

        //结果集合分页
        builder.from(0).size(2);

        //排序
        builder.sort("createTime",SortOrder.ASC);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • 聚合查询-求和
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 聚合查询 sum
     * @throws IOException
     */
    @Test
    public void search30() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件搜索
        builder.query(QueryBuilders.matchAllQuery());
        //聚合查询
        AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");
        builder.aggregation(aggregation);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • 聚合查询-求平均值
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 聚合查询 avg
     * @throws IOException
     */
    @Test
    public void search31() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件搜索
        builder.query(QueryBuilders.matchAllQuery());
        //聚合查询
        AggregationBuilder aggregation = AggregationBuilders.avg("avg_age").field("age");
        builder.aggregation(aggregation);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • 聚合查询-计数
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 聚合查询 count
     * @throws IOException
     */
    @Test
    public void search32() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件搜索
        builder.query(QueryBuilders.matchAllQuery());
        //聚合查询
        AggregationBuilder aggregation = AggregationBuilders.count("count_age").field("age");
        builder.aggregation(aggregation);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}
  • 聚合查询-分组
代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 聚合查询 分组
     * @throws IOException
     */
    @Test
    public void search33() throws IOException {
        // 创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //条件搜索
        builder.query(QueryBuilders.matchAllQuery());
        //聚合查询
        AggregationBuilder aggregation = AggregationBuilders.terms("tag_createTime").field("createTime")
                .subAggregation(AggregationBuilders.count("count_age").field("age")) //计数
                .subAggregation(AggregationBuilders.sum("sum_age").field("age")) //求和
                .subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值

        builder.aggregation(aggregation);

        //不输出原始数据
        builder.size(0);

        //搜索
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cs_index");
        searchRequest.types("_doc");
        searchRequest.source(builder);
        // 执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 解析查询结果
        System.out.println(response.toString());
    }
}

三、小结

本文主要围绕 SpringBoot 整合 ElasticSearch 进行各种高级查询的介绍,在下篇文章中,我们会重点介绍 es 的性能调优!

文章内容难免会有些遗漏的地方,欢迎网友批评指出!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java极客技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、代码实践
  • 三、小结
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档