当前位置: 首页 > news >正文

Elasticsearch:驾驭数据浪潮,利用Java API与Elasticsearch DSL构建智能搜索

在当今数据驱动的企业环境中,利用Java API与Elasticsearch DSL构建的智能搜索应用扮演着至关重要的角色。它不仅能够高效处理和分析海量数据,还能提供精准、即时的搜索结果,极大地提升了信息检索的效率和准确性。通过灵活运用DSL查询,企业可以实现复杂的搜索需求,支持决策制定。

目录

查询步骤

RestClient查询

准备基础代码

代码示例与解读

叶子查询

全文检索查询

match查询

multi_match查询

精确查询

range查询

term查询

复杂查询

bool查询

排序和分页


查询步骤

之前说过,由于Elasticsearch对外暴露的接口都是Restful风格的接口,因此JavaAPI调用就是在发送Http请求

查询的基本步骤如下:

  1. 创建request对象,这次是搜索,所以是SearchRequest
  2. 准备请求参数,也就是查询DSL对应的JSON参数
  3. 发起请求
  4. 解析响应,响应结果相对复杂,需要逐层解析

事实上,我们必须明白使用Java API 实现DSL的过程是:根据DSL语句拼接条件。

RestClient查询

新建一个ElasticSearchTest测试类

准备基础代码

 private RestHighLevelClient client;

    /**
     * 创建ES客户端
     */
    @BeforeEach
    void setUp() {
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://你自己的虚拟机地址:9200")
        ));
    }

    /**
     * 关闭ES客户端
     * @throws IOException
     */
    @AfterEach
    void tearDown() throws IOException {
        if (client != null) {
            client.close();
        }
    }

    /**
     * 测试连接
     */
    @Test
    void testConnection() {
        System.out.println("client = " + client);
    }

代码示例与解读

    /**
     * 测试查询所有
     * @throws IOException
     */
    @Test
    void testMatchAll() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(QueryBuilders.matchAllQuery());
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

解读:

  1. 第一步,创建SearchRequest对象,指定索引库名
  2. 第二步,利用request.source()构建DSL,DSL中可以包含查询、分页、排序、高亮
  3. 第三步,利用client.search()发送请求,得到响应
  4. 第四步,解析请求

这里关键的API有两个,一个是request.source(),它构建的就是DSL中的完整JSON参数。

另一个是QueryBuilders,其中包含了我们学习过的各种叶子查询复合查询等。

现在通过解析请求的方法:

    /**
     * 处理响应
     * @param response
     */
    private void handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 2.遍历结果数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            // 3.得到_source,也就是原始json文档
            String source = hit.getSourceAsString();
            // 4.反序列化并打印
            ItemDoc item = JSONUtil.toBean(source, ItemDoc.class);
            System.out.println(item);
        }
    }

叶子查询

全文检索查询

match查询

    /**
     * 测试查询所有
     * @throws IOException
     */
    @Test
    void testMatchAll() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(QueryBuilders.matchAllQuery());
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

实现效果如下:

multi_match查询

    /**
     * 测试多字段查询
     * @throws IOException
     */
    @Test
    void testMultiMatch() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(QueryBuilders.multiMatchQuery("Apple", "name", "category"));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

实现效果如下:(即必须name和category中都带有“Apple”)

精确查询

range查询

    /**
     * 测试范围查询
     * @throws IOException
     */
    @Test
    void testRange() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(QueryBuilders.rangeQuery("price").gte(100000).lte(300000));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    

实现效果如下:

term查询

    /**
     * 测试精确查询
     * @throws IOException
     */
    @Test
    void testTerm() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(QueryBuilders.termQuery("brand", "Huawei"));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

实现效果如下:

复杂查询

bool查询

    /**
     * 测试复杂条件查询
     * @throws IOException
     */
    @Test
    void testSearch() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        request.source().query(
                QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("name", "手机"))
                        .filter(QueryBuilders.termQuery("brand", "Huawei"))
                        .filter(QueryBuilders.rangeQuery("price").lt(1000000))
        );
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

实现效果如下:

排序和分页

    /**
     * 分页和排序
     * @throws IOException
     */
    @Test
    void testPageAndSort() throws IOException {
        int pageNo = 1, pageSize = 5;

        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        // 2.1.搜索条件参数
        request.source().query(QueryBuilders.matchQuery("name", "电脑"));
        // 2.2.排序参数
        request.source().
                sort("sold", SortOrder.DESC).
                sort("price", SortOrder.ASC);
        // 2.3.分页参数
        request.source().from((pageNo - 1) * pageSize).size(pageSize);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

实现效果如下:(name中包含“电脑”,现役sold降序排序,sold相同,以price升序排序,展示第一页,展示五条)

高亮

    /**
     * 高亮
     * @throws IOException
     */
    @Test
    void testHighlight() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.组织请求参数
        // 2.1.query条件
        request.source().query(QueryBuilders.matchQuery("name", "手机"));
        // 2.2.高亮条件
        request.source().highlighter(
                SearchSourceBuilder.highlight()
                        .field("name")
                        .preTags("<em>")
                        .postTags("</em>")
        );
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleHighResponse(response);
    }

    /**
     * 处理高亮响应
     * @param response
     */

    private void handleHighResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 2.遍历结果数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            // 3.得到_source,也就是原始json文档
            String source = hit.getSourceAsString();
            // 4.反序列化
            ItemDoc item = JSONUtil.toBean(source, ItemDoc.class);
            // 5.获取高亮结果
            Map<String, HighlightField> hfs = hit.getHighlightFields();
            if (CollUtil.isNotEmpty(hfs)) {
                // 5.1.有高亮结果,获取name的高亮结果
                HighlightField hf = hfs.get("name");
                if (hf != null) {
                    // 5.2.获取第一个高亮结果片段,就是商品名称的高亮值
                    String hfName = hf.getFragments()[0].string();
                    item.setName(hfName);
                }
            }
            System.out.println(item);
        }
    }

实现效果如下:

相关文章:

  • DataWorks (数据工厂)介绍
  • 【word】电子签名设置、保存和调用
  • 【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现
  • QT实现简约美观的动画Checkbox
  • 深入理解Linux内存缓存:提升性能的关键
  • 每日一题-奶酪题(蓝桥杯)【模拟】
  • LeeCode题库第四十一题
  • 《白帽子讲 Web 安全》之深入同源策略(万字详解)
  • 数字内容体验个性化推荐的核心优势是什么?
  • 力扣203.移除链表元素
  • iOS应用手动脱壳砸壳教程
  • 代码随想录算法训练营第三十一天 | 56. 合并区间 738.单调递增的数字
  • linux下自旋锁(spin_lock)
  • 回归算法模型总结
  • unity pico开发 四 物体交互 抓取 交互层级
  • 芯麦GC1262E:电脑散热风扇驱动芯片的优质之选并可替代传统的APX9262S茂达芯片
  • OFD签章技术和情景案例
  • M系列芯片 MacOS 在 Conda 环境中安装 TensorFlow 2 和 Keras 3 完整指南
  • 【C++】stack和queue以及priority_queue的使用以及模拟实现
  • 《基于HarmonyOS NEXT API 12+,搭建新闻创作智能写作引擎》
  • 奥斯卡新规:评委必须看完影片再投票;网友:以前不是啊?
  • 三家“券商系”公募同日变更掌门人,新董事长均为公司股东方老将
  • 《求是》杂志发表习近平总书记重要文章《激励新时代青年在中国式现代化建设中挺膺担当》
  • 坚持科技创新引领,赢得未来发展新优势
  • 厚重与潮流交织,淮安展现“运河之都”全新城市想象
  • 铁路五一假期运输今日启动,预计发送旅客1.44亿人次