Easysearch Java SDK 2.0.x 使用指南(二)

在 上一篇文章 中,我们介绍了 Easysearch Java SDK 2.0.x 的基本使用和批量操作。本文将深入探讨索引管理相关的功能,包括索引的创建、删除、开关、刷新、滚动等操作,以及新版 SDK 提供的同步和异步两种调用方式。

SDK 的对象构建有两种方式

1. 传统的 Builder 方式

最基础的方式,像这样:

CreateIndexResponse createResponse = client.indices().create(
    new CreateIndexRequest.Builder()
        .index("my-index")
        .aliases("foo",
            new Alias.Builder().isWriteIndex(true).build()
        )
        .build()
);

优点简单直观,但稍显笨重。

2. Lambda 表达式方式

这才是推荐的写法,简洁优雅:

CreateIndexResponse createResponse = client.indices()
    .create(c -> c
        .index("my-index")
        .aliases("foo", a -> a
            .isWriteIndex(true)
        )
    );

Lambda 方式不仅代码少,最大的优点是不用记那么多 Builder 类名。尤其是写复杂查询的时候,代码层次感特别强:

// 命名建议:用 b0、b1 这样的简写表示嵌套层级
SearchResponse<Doc> results = client.search(b0 -> b0
    .index("my-index")
    .query(b1 -> b1
        .bool(b2 -> b2
            .must(b3 -> b3
                .match(b4 -> b4
                    .field("title")
                    .query("搜索")
                )
            )
            .filter(b3 -> b3
                .range(b4 -> b4
                    .field("date")
                    .gte("2024-01-01")
                )
            )
        )
    ),
    Doc.class
);

好了,说回索引管理

啥是索引管理?

简单来说就是对索引进行增删改查的一些基本操作。比如:

  • 建个新索引
  • 删掉不要的索引
  • 关闭/打开某个索引
  • 刷新一下让数据立马能搜到
  • 清个缓存
  • 整理一下索引段(让搜索更快)

新版 SDK 在这块的设计特别贴心,同步异步都支持,用起来特别顺手。

同步方式怎么用?

上代码!下面这段代码基本涵盖了日常用到的所有索引管理操作:

    String index = "test1";
    // 先看看索引在不在
    if (client.indices().exists(r -> r.index(index)).value()) {
        LOGGER.info("Deleting index " + index);
        // 在的话就删掉重来
        DeleteIndexResponse deleteIndexResponse =
            client.indices().delete(new DeleteIndexRequest.Builder().index(index).build());
        LOGGER.info(deleteIndexResponse.toString());
    }

    // 建个新的
    LOGGER.info("Creating index " + index);
    CreateIndexResponse createIndexResponse =
        client.indices().create(req -> req.index(index));

    // 关闭索引
    CloseIndexResponse closeIndexResponse =
        client.indices().close(req -> req.index(index));

    // 打开索引
    OpenResponse openResponse =
        client.indices().open(req -> req.index(index));

    // 刷新一下,让刚写入的数据马上能搜到
    RefreshResponse refreshResponse =
        client.indices().refresh(req -> req.index(index));

    // 把内存里的数据都写到磁盘上
    FlushResponse flushResponse =
        client.indices().flush(req -> req.index(index));

    // 整理一下索引段,搜索会快很多
    // maxNumSegments(1L) 意思是整理成一个段
    ForcemergeResponse forcemergeResponse =
        client.indices().forcemerge(req -> req.index(index).maxNumSegments(1L));

看代码就能明白,这些操作都特别直观,基本上方法名就能告诉你它是干啥的。而且返回的 Response 对象里都带着详细的执行结果,出了问题很容易排查。

异步方式又是咋回事?

有时候你可能不想等着这些操作一个个完成,这时候就可以用异步方式:


    String index = "test1";
    EasysearchAsyncClient asyncClient = SampleClient.createAsyncClient();

    // 用CompletableFuture串起来一串操作
    asyncClient.indices().exists(req -> req.index(index))
        .thenCompose(exists -> {
            if (exists.value()) {
                LOGGER.info("Deleting index " + index);
                return asyncClient.indices().delete(r -> r.index(index))
                    .thenAccept(deleteResponse -> {
                        LOGGER.info(deleteResponse);
                    });
            }
            return CompletableFuture.completedFuture(null);
        })
        .thenCompose(v -> {
            LOGGER.info("Creating index " + index);
            return asyncClient.indices().create(req -> req.index(index));
        })
        .whenComplete((createResponse, throwable) -> {
            if (throwable != null) {
                LOGGER.error("哎呀出错了", throwable);
            } else {
                LOGGER.info("搞定!");
            }
        })
        .get(30, TimeUnit.SECONDS); // 最多等30秒

异步方式看起来代码多了点,但是好处也很明显:

  1. 不会卡住主线程
  2. 可以并发执行多个操作
  3. 配合 CompletableFuture 能实现很多花样

小贴士

  1. 选哪种方式?

    • 简单场景用同步,代码简单直观
    • 要并发或者不想阻塞就用异步
  2. 记得处理异常

    • 同步的就直接 try-catch
    • 异步的用 whenComplete 或 exceptionally 来处理
  3. 性能方面

    • force merge 挺耗资源的,建议半夜执行
    • refresh 太频繁会影响写入性能,根据需要权衡

自动翻转 (Rollover)

在管理 Easysearch 索引时,我们经常需要控制单个索引的大小和时间跨度。Easysearch 的 Rollover API 提供了一个优雅的解决方案,允许我们基于特定条件自动创建新索引。本文将介绍如何使用 Java API 实现索引 rollover。

什么是 Rollover?

Rollover 是一种索引管理机制,当现有索引满足一个或多个条件时(如达到一定大小、文档数量或时间),会自动创建一个新索引。这对于日志管理等场景特别有用。

实现示例

首先,我们需要创建一个初始索引并设置别名:

String index = "test-00001";
// 如果索引存在则删除
if (client.indices().exists(r -> r.index(index)).value()) {
    client.indices().delete(new DeleteIndexRequest.Builder().index(index).build());
}

// 创建索引并设置别名
client.indices().create(req -> req
    .index(index)
    .aliases("test_log", a -> a.isWriteIndex(true)));

配置 Rollover 条件

有两种方式配置 rollover 条件:

方式一:使用 Java API

RolloverResponse res = client.indices().rollover(req -> req
    .alias("test_log")
    .conditions(c -> c
        .maxDocs(100L)        // 文档数量超过100
        .maxAge(b -> b.time("7d"))  // 索引年龄超过7天
        .maxSize("5gb")));    // 索引大小超过5GB

方式二:使用 JSON 配置

String conditionsJson = """
{
  "conditions": {
    "max_docs": 100,
    "max_age": "7d",
    "max_size": "5gb"
  }
}
""";

RolloverResponse response = client.indices().rollover(req -> req
    .alias("test_log")
    .withJson(new StringReader(conditionsJson))
);

Rollover 条件说明

  • max_docs: 索引中的最大文档数
  • max_age: 索引最大存在时间
  • max_size: 索引的最大存储大小

当满足任一条件时,系统会自动创建新索引。新索引的命名规则是将原索引名称中的数字部分加 1。


想要了解更多?

  • 客户端 Maven 地址: https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2
  • 更详细的文档和示例代码在 官网 持续更新中,请随时关注!

大家有啥问题或者建议,也欢迎随时反馈!

关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

官网文档:https://infinilabs.cn/docs/latest/easysearch

作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scala——身份证号码查询籍贯

object Test_身份证查询籍贯 { def main(args: Array[String]): Unit { val code "42005200210030051".substring(0,2) println(code) //判断42是哪个省的 //湖北 // if(code "42"){ // println("42对应省份为&#xff1a;湖北") // }else…

分布式系统架构:限流设计模式

1.为什么要限流&#xff1f; 任何一个系统的运算、存储、网络资源都不是无限的&#xff0c;当系统资源不足以支撑外部超过预期的突发流量时&#xff0c;就应该要有取舍&#xff0c;建立面对超额流量自我保护的机制&#xff0c;而这个机制就是微服务中常说的“限流” 2.四种限流…

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题&#xff08;选择题&#xff09; 题目总数&#xff1a;5 总分数&#xff1a;50 选择题 第 1 题 单选题 Scratch运行以下程宇后&#xff0c;小兔子会&#xff08; &#xff09;。 A. 变小 B. 变大 C. 变色 D. …

Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类

Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类 CIFAR10数据集ParNet架构特点优势应用 ParNet结构代码详解结构代码代码详解SSEParNetBlock 类DownsamplingBlock 类FusionBlock 类ParNet 类 训练过程和测试结果代码汇总parnet.pytrain.pytest.py 前面文章我们构…

Docker核心技术和实现原理

目录 1. Docker镜像原理介绍1.1 操作系统基础1.2 Union FS(联合文件系统)1.3 再看 Docker 镜像是什么 2. 镜像的实现原理2.1 Docker 分层存储实现原理2.2 docker 镜像加载原理 3. 镜像分层存储实战3.1 基础知识3.2 实战过程 4. overlay 文件系统工作实战5. Docker卷原理介绍5.1…

AI的进阶之路:从机器学习到深度学习的演变(二)

AI的进阶之路&#xff1a;从机器学习到深度学习的演变&#xff08;一&#xff09; 三、机器学习&#xff08;ML&#xff09;&#xff1a;AI的核心驱动力 3.1 机器学习的核心原理 机器学习&#xff08;Machine Learning, ML&#xff09;突破了传统编程的局限&#xff0c;它不再…

34.正则表达式

python正则表达式&#xff0c;使用re模块&#xff0c;模块中三个基础方法来做正则匹配。 match re.match(匹配规则&#xff0c; 被匹配的字符串) 从字符串开头进行匹配&#xff0c;匹配成功返回匹配对象&#xff08;包含匹配的信息&#xff09;&#xff0c;匹配不成功返回空。…

xpath插件安装与使用

1.背景 在使用python爬取页面数据时,经常会遇到解析页面数据,有一个非常好用的插件工具 是:xpath插件 2.安装与使用步骤 步骤1:准备xpath插件,并解压 步骤2:添加扩展程序 点击扩展程序后: 点击:加载已解压的扩展程序 安装成功后: 关闭浏览器,重新打开浏览器就可以使用了 步…

安徽医科大学卫生管理学院与和鲸科技签署“101 数智领航计划”,共拓“医学+AI”学科建设与人才培养

为进一步强化卫生健康人才培养关键方向&#xff0c;着力加强“医学AI”的复合型交叉人才培养&#xff0c;2024 年 12 月 13 日&#xff0c;安徽医科大学卫生管理学院与上海和今信息科技有限公司&#xff08;以下简称“和鲸科技”&#xff09;召开校企合作洽谈会&#xff0c;并正…

spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))

目录 一、单个字符串或对象引用的注入。 &#xff08;1&#xff09;简单案例演示。 1、项目的基本结构和类介绍。 2、接口"UserDao"代码。 3、实现类"UserDaoImpl"代码。 4、spring配置文件。 5、测试类(MainApp)。 6、查看执行结果。(对应成员变量成功注入…

三格电子——新品IE103转ModbusTCP网关

型号&#xff1a;SG-TCP-IEC103 产品概述 IE103转ModbusTCP网关型号SG-TCP-IEC103&#xff0c;是三格电子推出的工业级网关&#xff08;以下简称网关&#xff09;&#xff0c;主要用于IEC103数据采集、DLT645-1997/2007数据采集&#xff0c;IEC103支持遥测和遥信&#xff0c;可…

leetcode-283.移动零-day13

方法一&#xff1a;双指针遇 0 交换 1. 基本思路回顾 该方法使用了两个指针m和i&#xff0c;m用于标记当前已经处理好的非零元素应该放置的位置&#xff0c;i用于遍历整个数组。当遇到nums[m]为0时&#xff0c;会通过内层while循环找到下一个非零元素&#xff08;如果存在的话…

基于LabVIEW的USRP信道测量开发

随着无线通信技术的不断发展&#xff0c;基于软件无线电的设备&#xff08;如USRP&#xff09;在信道测量、无线通信测试等领域扮演着重要角色。通过LabVIEW与USRP的结合&#xff0c;开发者可以实现信号生成、接收及信道估计等功能。尽管LabVIEW提供了丰富的信号处理工具和图形…

Go怎么做性能优化工具篇之基准测试

一、什么是基准测试&#xff08;Benchmark&#xff09; 在 Go 中&#xff0c;基准测试是通过创建以 Benchmark 开头的函数&#xff0c;并接收一个 *testing.B 类型的参数来实现的。testing.B 提供了控制基准测试执行的接口&#xff0c;比如设置测试执行的次数、记录每次执行的…

Windows下使用git配置gitee远程仓库

目录 使用git配置&#xff08;传统方法&#xff09; 1、在桌面新建一个文件夹 2、git clone [ur1] 3、git branch查看分支 4、git branch新建分支&#xff08;重要&#xff09; 5、git push推送新分支 简单版&#xff08;使用git小乌龟&#xff09; 官网下载&#xff1…

DotNetBrowser 3.0.0 正式发布!

&#x1f6e0;️ 重要消息&#xff1a;DotNetBrowser 3.0.0 正式发布&#xff01; 我们很高兴向您介绍全新的 DotNetBrowser 3.0.0 版本。此次更新带来了多项重要功能与优化&#xff0c;进一步提升了 Web 开发的效率和体验。 &#x1f4e2; DotNetBrowser 3.0.0 包含哪些新功…

【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题

目录 为什么要结合项目与算法&#xff1f; 1. 蓝桥杯与《苍穹外卖》项目的结合 实例&#xff1a;基于蓝桥杯算法思想的订单配送路径规划 问题描述&#xff1a; 代码实现&#xff1a;使用动态规划解决旅行商问题 代码解析&#xff1a; 为什么这个题目与蓝桥杯相关&#x…

严格推导质点曲线运动的运动学方程

前言 相当一部分物理学书籍在推导质点曲线运动的运动学方程时&#xff0c;采用的都是先建立位移的微元 Δ r ⃗ \Delta \vec{r} Δr &#xff0c;然后几何近似求极限的方法。这种方法虽然能得到正确的结论&#xff0c;但数学上的严格性略有欠缺&#xff0c;且过程繁琐。考虑到…

【gym】理解gym并测试gym小游戏CartPole (一)

一、gym与文件位置的联合理解 import gym import inspect# 加载 CliffWalking 环境 env gym.make(CliffWalking-v0)# 获取环境的类 env_class type(env)# 获取环境类所在的文件路径 file_path inspect.getfile(env_class)print(f"The source code for CliffWalking-v0…

Mac升级macOS 15 Sequoia后,无法ssh连接本地虚拟机

现象 macOS 15后&#xff0c;无法ssh连接本地启动的虚拟机&#xff0c;提示错误&#xff1a; No route to host&#xff0c;也ping不通。包括UTM、Parallels Desktop这两个虚拟机软件。之前都是没问题的&#xff0c;通过一些简单排查&#xff0c;目前没发现什么问题。 在虚拟…