elasticsearch 实战

news2024/11/27 8:41:07

文章目录

      • 项目介绍
      • 导入项目
  • Elasticsearch Java API 查询文档
    • 快速入门
      • 发起查询请求
      • 解析响应
      • 完整代码
    • match查询
    • 精确查询
    • 布尔查询
    • 排序、分页
    • 高亮
      • 高亮请求构建
      • 高亮结果解析

项目介绍

本项目是一个由spring boot 3.0.2在gradle 8.4和java 21的环境下搭建的elasticsearch项目demo,这个项目是基于新版的Elasticsearch Java API 制作的,符合最新的框架要求,由于是运用了Elasticsearch新版的java jar包,所以在查询的时候使用了大量的Stream流式编程和闭包,亦可以作为流式编程的巩固。

导入项目

项目可以使用文章绑定的资源,或者去底部的GitHub地址下载

Elasticsearch Java API 查询文档

快速入门

我们以match_all查询为例

发起查询请求

在这里插入图片描述

代码解读
上面的代码使用了流式编程的思想,首先选择用search表示是选择查询模式,然后用index决定搜索的索引库,然后用query构建查询索引,然后选择查询模式matchAll。

es中的查询语句

GET hotel/_search
{
  "query": {
    "match_all": {}
  }
}

解析响应

elasticsearch返回的结果是一个JSON字符串,结构包含:

  • hits:命中的结果
    • total:总条数,其中的value是具体的总条数值
    • max_score:所有结果中得分最高的文档的相关性算分
    • hits:搜索结果的文档数组,其中的每个文档都是一个json对象
      • source:文档中的原始数据,也是json转化成实体类的对象

因此,我们解析响应结果,就是逐层解析JSON字符串,流程如下:

  • HitsMetadata:通过response.hits()获取,就是JSON中的最外层的hits,代表命中的结果
    • HitsMetadata.total().value():获取总条数信息
    • SearchHits#getHits():获取SearchHit数组,也就是文档数组

完整代码

完整代码如下:

    @Test
    void testMatchAll() throws IOException {
//进行查询
        SearchResponse<HotelDoc> response = esClient.search(s -> s
                        .index("hotel")
                        .query(q -> q
                                .matchAll(m->m)),
                HotelDoc.class
        );
        handleResponse(response);
    }
    private void handleResponse( SearchResponse<HotelDoc> response) {
        HitsMetadata<HotelDoc> searchHits = response.hits();
        // 4.1.总条数
        long total = searchHits.total().value();
        System.out.println("总条数:" + total);
        // 4.2.获取文档数组
        List<Hit<HotelDoc>>  hits = searchHits.hits();
        // 4.3.遍历
        hits.forEach(i->{
            // 4.4 自动序列化
            HotelDoc hotelDoc = i.source();
            // 4.6.处理高亮结果
            // 1)获取高亮字段和高亮数据的map
            Map<String, List<String>>  map = i.highlight();
            if (map!=null){
                // 2)根据字段名,获取高亮结果
                List<String> name = map.get("name");
                if (name!=null){
                    // 3)获取高亮结果字符串数组中的第1个元素
                    String hName= name.get(0);
                    // 4)把高亮结果放到HotelDoc中
                    hotelDoc.setName(hName);
                }
            }
            System.out.println(hotelDoc);
//            System.out.println(i.highlight());
        });

        }

match查询

全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query的部分。

在这里插入图片描述

因此,Java代码上的差异主要是request.source().query()中的参数了。同样是利用QueryBuilders提供的方法:

而结果解析代码则完全一致,可以抽取并共享。

完整代码如下:

    @Test
    void testMatch() throws IOException {

        SearchResponse<HotelDoc> response = esClient.search(i->i
                .index("hotel")
                .query(q->q.match(t->t
                        .field("all")//设置请求字段
                        .query("如家")//设置请求参数
                )),
                HotelDoc.class
        );
        handleResponse(response);
    }

精确查询

精确查询主要是两者:

  • term:词条精确匹配
  • range:范围查询

与之前的查询相比,差异同样在查询条件,其它都一样。

es语句

GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  }
}

查询条件构造的API如下:


        SearchResponse<HotelDoc> response = esClient.search(s -> s
                        .index("hotel")
                        .query(q->q.
                                    term(t->t
                                    .field("city")
                                    .value("上海"))),

布尔查询

布尔查询是用must、must_not、filter等方式组合其它查询,代码示例如下:

es语句

GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  }
}

完整代码如下:

    @Test
    void testMatch() throws IOException {

        SearchResponse<HotelDoc> response = esClient.search(i->i
                .index("hotel")
                .query(q->q.match(t->t
                        .field("all")//设置请求字段
                        .query("如家")//设置请求参数
                )),
                HotelDoc.class
        );
        handleResponse(response);
    }

排序、分页

es语句

GET hotel/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5,
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]

}

完整代码示例:

@Test
void testPageAndSort() throws IOException {
    // 页码,每页大小
    int page = 1, size = 5;

    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    // 2.1.query
    request.source().query(QueryBuilders.matchAllQuery());
    // 2.2.排序 sort
    request.source().sort("price", SortOrder.ASC);
    // 2.3.分页 from、size
    request.source().from((page - 1) * size).size(5);
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse(response);

}

高亮

高亮的代码与之前代码差异较大,有两点:

  • 查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。
  • 结果解析:结果除了要解析_source文档数据,还要解析高亮结果

高亮请求构建

es语句

GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  },
  "highlight": {
    "fields": {"name": {"require_field_match": "false"}}
  }
}

上述代码省略了查询条件部分,但是大家不要忘了:高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。

完整代码如下:

    @Test
    void testHighlight() throws IOException {
        SearchResponse<HotelDoc> response = esClient.search(s->s
                        .index("hotel")
                        .query(q->q.match(t->t
                                .field("all")//设置请求字段
                                .query("如家")//设置请求参数
                        ))
                        .highlight(h->h
                                .fields("name",f->f.requireFieldMatch(false))),
                HotelDoc.class
        );
        handleResponse(response);
    }

高亮结果解析

高亮的结果与查询的文档结果默认是分离的,并不在一起。

代码解读:

  • 第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象
  • 第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值
  • 第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField
  • 第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了
  • 第五步:用高亮的结果替换HotelDoc中的非高亮结果

完整代码如下:

private void handleResponse(SearchResponse response) {
    // 4.解析响应
    SearchHits searchHits = response.getHits();
    // 4.1.获取总条数
    long total = searchHits.getTotalHits().value;
    System.out.println("共搜索到" + total + "条数据");
    // 4.2.文档数组
    SearchHit[] hits = searchHits.getHits();
    // 4.3.遍历
    for (SearchHit hit : hits) {
        // 获取文档source
        String json = hit.getSourceAsString();
        // 反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        // 获取高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (!CollectionUtils.isEmpty(highlightFields)) {
            // 根据字段名获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if (highlightField != null) {
                // 获取高亮值
                String name = highlightField.getFragments()[0].string();
                // 覆盖非高亮结果
                hotelDoc.setName(name);
            }
        }
        System.out.println("hotelDoc = " + hotelDoc);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1257315.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习的复习笔记3-回归的细谈

一、回归的细分 机器学习中的回归问题是一种用于预测连续型输出变量的任务。回归问题的类型和特点如下&#xff1a; 总之&#xff0c;支持向量回归是一种用于解决回归问题的机器学习方法&#xff0c;通过寻找支持向量和引入容忍度范围来建立回归模型&#xff0c;能够处理非线性…

【腾讯云 HAI域探秘】基于高性能应用服务器HAI部署的 ChatGLM2-6B模型,我开发了AI办公助手,公司行政小姐姐用了都说好!

目录 前言 一、腾讯云HAI介绍&#xff1a; 1、即插即用 轻松上手 2、横向对比 青出于蓝 3、多种高性能应用部署场景 二、腾讯云HAI一键部署并使用ChatGLM2-6B快速实现开发者所需的相关API服务 1、登录 高性能应用服务 HAI 控制台 2、点击 新建 选择 AI模型&#xff0c;…

【GD32307E-START】RT-Thread移植测试

【GD32307E-START】RT-Thread移植测试 1. 软硬件平台 GD32F307E-START Board开发板MDK-ARM KeilGCC Makefile 2. 物联网RTOS—RT-Thread RT-Thread RT-Thread诞生于2006年&#xff0c;是一款以开源、中立、社区化发展起来的物联网操作系统。 RT-Thread主要采用 C 语言编写…

RH2288H V3服务器使用ISO安装系统

1.配置和服务器相同网段地址&#xff0c;RH2288H V3服务器bmc管理网口默认IP是192.168.2.100/24&#xff0c;默认用户root&#xff0c;默认Huawei12#$&#xff0c;网线连接BMC口&#xff0c;登录。默认密码可以在开机时按del键进入配置页面修改 2.配置raid&#xff0c;生产环境…

SpringCloud 微服务全栈体系(十八)

第十一章 分布式搜索引擎 elasticsearch 八、RestClient 查询文档 文档的查询同样适用 RestHighLevelClient 对象&#xff0c;基本步骤包括&#xff1a; 准备 Request 对象准备请求参数发起请求解析响应 1. 快速入门 以 match_all 查询为例 1.1 发起查询请求 代码解读&…

基于Java SSM框架+Vue实现药品销售进销存网站项目【项目源码+论文说明】

基于java的SSM框架Vue实现药品销售进销存网站演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于药品管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了…

岂曰无衣 汉家衣裳再现锦绣美景

——福州第五届1122汉服节出行盛大开幕11月25日下午&#xff0c;闽江之心海丝广场&#xff0c;一场盛大的汉服文化节——福州第五届1122汉服节出行活动在这里隆重开幕。这个被誉为“穿在身上的历史”的传统文化&#xff0c;在这片古老而神秘的土地上焕发出新的生机与活力。据了…

Win10电脑用U盘重装系统的步骤

在Win10电脑中&#xff0c;用户遇到了无法解决的系统问题&#xff0c;用户这时候就可以考虑重装Win10系统&#xff0c;这样即可轻松解决问题&#xff0c;从而满足自己的操作需求。接下来小编给大家详细介绍关于Win10电脑中用U盘重装系统的教程步骤。 准备工作 1. 一台正常联网可…

group by

引入 日常开发中&#xff0c;我们经常会使用到group by。你是否知道group by的工作原理呢&#xff1f;group by和having有什么区别呢&#xff1f;group by的优化思路是怎样的呢&#xff1f;使用group by有哪些需要注意的问题呢&#xff1f; 使用group by的简单例子group by 工…

火力发电厂电气一次部分初步设计(论文+图纸)

1 原始资料 设计电厂为中型是凝汽式发电厂&#xff0c;共4台发电机组&#xff0c;2台75MW机组&#xff0c;2台50MW机组&#xff0c;总的装机容量为250MW&#xff0c;占系统容量的比例为&#xff1a; 250/(3500250)100%6.7%<15%&#xff0c;未超过电力系统的检修备用容量和…

深入理解JMM以及并发三大特性(2)

书接上文 文章目录 (1)CPU高速缓存(2)缓冲一致性(3)总线仲裁机制(4)总线窥探(Bus Snooping) 前面介绍到实现可见性&#xff0c;底层常用的一种方案是使用内存屏障&#xff0c;而内存屏障在汇编层面又是使用lock前缀指令来实现的&#xff0c;所以这里来介绍一下lock前缀指令。 …

skywalking 简单操作文档

1.1. 基础概念 1.1.1. 概述 SkyWalking是 apache基金会下面的一个开源 APM项目&#xff0c;为微服务架构和云原生架构系统设计。它通过探针自动收集所需的指标&#xff0c;并进行分布式追踪。通过这些调用链路以及指标&#xff0c;Skywalking APM会感知应用间关系和服务间关系…

酷开科技 | 酷开系统,让你与家人共度美好时光!

在日渐繁忙的生活中&#xff0c;我们常常会忽略和家人朋友的相处时光&#xff0c;有时候&#xff0c;我们亟需一种休闲方式&#xff0c;让家庭成员能够围坐在一起&#xff0c;享受无忧无虑的温馨和欢笑。酷开科技&#xff0c;致力于为消费者提供舒适的产品和服务内容&#xff0…

Windows11系统如何将此电脑和回收站图标放置在桌面上?

Windows11系统如何将此电脑和回收站图标放置在桌面上&#xff1f; 如下图所示&#xff0c;点击“开始”图标&#xff0c;&#xff0c;找到“设置”&#xff0c; 如下图所示&#xff0c;进入设置后&#xff0c;找到个性化—主题&#xff0c; 如下图所示&#xff0c;在个性化—主…

免费分享一套基于springboot的餐饮美食分享平台系统,挺漂亮的

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的基于springboot的餐饮美食分享平台系统&#xff0c;分享下哈。 项目视频演示 【免费】基于springboot的餐饮美食分享平台 Java毕业设计_哔哩哔哩_bilibili【免费】基于springboot的餐饮美食分享平台 Java毕…

校园导游程序及通信线路设计(结尾附着总源码)

校园导游程序及通信线路设计 摘  要 新生或来访客人刚到校园&#xff0c;对校园的环境不熟悉。就需要一个导游介绍景点&#xff0c;推荐到下一个景点的最佳路径等。随着科技的发展&#xff0c;社会的进步&#xff0c;人们对便捷的追求也越来越高。为了减少人力和时间。针对对…

VMWare虚拟机ubuntu克隆打不开

ubuntu克隆打不开 复制的存有ubuntu克隆的文件夹&#xff0c;导入vmware打不开 说找不到这个文件&#xff0c;那就到目录把它的删掉 的删掉 换000001.vmdk后缀的

好用的基于layui的免费开源后台模版layuimini

发现一个好用的后台模版 基于layui的免费开源后台模版layuimini layuimini - 基于Layui的后台管理系统前端模板 easyadmin开源项目 EasyAdmin是基于ThinkPHP6.0Layui的快速开发的后台管理系统。 演示站点 演示地址&#xff1a;跳转提示&#xff08;账号&#xff1a;admin&a…

C++学习之路(六)C++ 实现简单的工具箱系统命令行应用 - 示例代码拆分讲解

简单的工具箱系统示例介绍: 这个示例展示了一个简单的工具箱框架&#xff0c;它涉及了几个关键概念和知识点&#xff1a; 面向对象编程 (OOP)&#xff1a;使用了类和继承的概念。Tool 是一个纯虚类&#xff0c;CalculatorTool 和 FileReaderTool 是其派生类。 多态&#xff1…

JavaScript WebApi(二) 详解

监听事件 介绍 事件监听是一种用于在特定条件下执行代码的编程技术。在Web开发中&#xff0c;事件监听器可以用于捕获和响应用户与页面交互的各种操作&#xff0c;如点击、滚动、输入等。 事件监听的基本原理是&#xff0c;通过在特定元素上注册事件监听器&#xff0c;当事件…