编辑此页面

在独立模式下使用 Hibernate Search 与 Elasticsearch/OpenSearch

您有一个 Quarkus 应用程序?您想为用户提供功能齐全的全文搜索?您来对地方了。

通过本指南,您将了解到如何快速将实体索引到 Elasticsearch 或 OpenSearch 集群中。我们还将探讨如何使用 Hibernate Search API 查询您的 Elasticsearch 或 OpenSearch 集群。

如果您想索引 Hibernate ORM 实体,请参阅 此专用指南

先决条件

要完成本指南,您需要

  • 大约 20 分钟

  • 一个 IDE

  • 已安装 JDK 17+ 并正确配置了 JAVA_HOME

  • Apache Maven 3.9.9

  • 一个正常工作的容器运行时(Docker 或 Podman

  • 如果您想使用它,可以选择 Quarkus CLI

  • 如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置

架构

本指南中介绍的应用程序允许管理一个(简单的)图书馆:您管理作者及其书籍。

实体存储在 Elasticsearch 集群中并被索引。

解决方案

我们建议您按照以下章节中的说明,逐步创建应用程序。但是,您可以直接转到完整的示例。

克隆 Git 存储库:git clone https://github.com/quarkusio/quarkus-quickstarts.git,或下载一个 存档

解决方案位于 hibernate-search-standalone-elasticsearch-quickstart 目录

提供的解决方案包含一些额外的元素,例如测试和测试基础架构。

创建 Maven 项目

首先,我们需要一个新项目。使用以下命令创建一个新项目

CLI
quarkus create app org.acme:hibernate-search-standalone-elasticsearch-quickstart \
    --extension='hibernate-search-standalone-elasticsearch,rest-jackson' \
    --no-code
cd hibernate-search-standalone-elasticsearch-quickstart

要创建 Gradle 项目,请添加 --gradle--gradle-kotlin-dsl 选项。

有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.24.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=hibernate-search-standalone-elasticsearch-quickstart \
    -Dextensions='hibernate-search-standalone-elasticsearch,rest-jackson' \
    -DnoCode
cd hibernate-search-standalone-elasticsearch-quickstart

要创建 Gradle 项目,请添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

对于 Windows 用户

  • 如果使用 cmd,(不要使用反斜杠 \ 并将所有内容放在同一行上)

  • 如果使用 Powershell,请将 -D 参数括在双引号中,例如 "-DprojectArtifactId=hibernate-search-standalone-elasticsearch-quickstart"

此命令生成一个 Maven 结构,导入以下扩展

  • Hibernate Search Standalone + Elasticsearch,

  • Quarkus REST(以前称为 RESTEasy Reactive)和 Jackson。

如果您已经配置了 Quarkus 项目,可以通过在项目根目录中运行以下命令将 hibernate-search-standalone-elasticsearch 扩展添加到您的项目中

CLI
quarkus extension add hibernate-search-standalone-elasticsearch
Maven
./mvnw quarkus:add-extension -Dextensions='hibernate-search-standalone-elasticsearch'
Gradle
./gradlew addExtension --extensions='hibernate-search-standalone-elasticsearch'

这会将以下内容添加到您的 pom.xml

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-search-standalone-elasticsearch</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-hibernate-search-standalone-elasticsearch")

创建基本类

首先,让我们在 model 子包中创建 BookAuthor 类。

package org.acme.hibernate.search.elasticsearch.model;

import java.util.List;
import java.util.Objects;

public class Author {

    public UUID id; (1)

    public String firstName;

    public String lastName;

    public List<Book> books;

    public Author(UUID id, String firstName, String lastName, List<Book> books) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.books = books;
    }
}
1 我们在这里使用公共字段,因为它们更短,并且对于本质上是数据类的字段没有封装的要求。

但是,如果您更喜欢使用私有字段和 getter/setter,那也是完全可以的,并且只要 getter/setter 符合 JavaBeans 命名约定(getSomething()/isSomething()/setSomething(…​)),它们就能完美运行。

package org.acme.hibernate.search.elasticsearch.model;

import java.util.Objects;

public class Book {

    public UUID id;

    public String title;

    public Book(UUID id, String title) {
        this.id = id;
        this.title = title;
    }
}

使用 Hibernate Search 注解

为我们的类启用全文搜索功能非常简单,只需添加一些注解即可。

让我们编辑 Author 实体以包含以下内容

package org.acme.hibernate.search.elasticsearch.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.hibernate.search.engine.backend.types.Sortable;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.DocumentId;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IdProjection;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ProjectionConstructor;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.SearchEntity;

@SearchEntity (1)
@Indexed (2)
public class Author {

    @DocumentId (3)
    public UUID id;

    @FullTextField(analyzer = "name") (4)
    @KeywordField(name = "firstName_sort", sortable = Sortable.YES, normalizer = "sort") (5)
    public String firstName;

    @FullTextField(analyzer = "name")
    @KeywordField(name = "lastName_sort", sortable = Sortable.YES, normalizer = "sort")
    public String lastName;

    @IndexedEmbedded (6)
    public List<Book> books = new ArrayList<>();

    public Author(UUID id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @ProjectionConstructor (7)
    public Author(@IdProjection UUID id, String firstName, String lastName, List<Book> books) {
        this( id, firstName, lastName );
        this.books = books;
    }
}
1 首先,我们将 Author 类型标记为 实体类型。简而言之,这意味着 Author 类型具有自己的、不同的生命周期(不与另一个类型绑定),并且每个 `BookAuthor` 实例都包含一个不可变的、唯一的标识符。
2 然后,让我们使用 @Indexed 注解将我们的 Author 实体注册为全文索引的一部分。
3 最后,我们通过定义文档标识符来完成强制配置。
4 @FullTextField 注解声明了一个专门为全文搜索量身定制的索引字段。特别是,我们必须定义一个分析器来拆分和分析 token(~单词)——稍后会详细介绍。
5 正如您所见,我们可以为同一个属性定义多个字段。这里,我们定义了一个具有特定名称的 @KeywordField。主要区别在于关键字字段不会被分词(字符串被保留为一个单独的 token),但可以被规范化(即过滤)——稍后会详细介绍。此字段被标记为可排序,因为我们的目的是使用它来对作者进行排序。
6 @IndexedEmbedded 的目的是将 Book 字段包含在 Author 索引中。在这种情况下,我们只使用默认配置:所有关联的 Book 实例的字段都包含在索引中(即 title 字段)。@IndexedEmbedded 还支持嵌套文档(使用 structure = NESTED 属性),但这里我们不需要。您还可以通过 includePaths/excludePaths 属性指定要嵌入到父索引中的字段,如果您不想要所有字段的话。
7 我们将一个(单个)构造函数标记为 @ProjectionConstructor,以便可以从索引内容中重建 Author 实例。

现在我们的作者已被索引,我们将需要映射书籍,以便此 @IndexedEmbedded 注解实际上嵌入了*一些内容*。

打开 Book 类并包含以下内容

package org.acme.hibernate.search.elasticsearch.model;

import java.util.Objects;
import java.util.UUID;

import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ProjectionConstructor;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.SearchEntity;

@SearchEntity (1)
public class Book {

    @KeywordField (2)
    public UUID id;

    @FullTextField(analyzer = "english") (3)
    public String title;

    @ProjectionConstructor (4)
    public Book(UUID id, String title) {
        this.id = id;
        this.title = title;
    }
}
1 我们也已将 Book 类型标记为 实体类型,但我们没有使用 @Indexed,因为我们决定不需要为书籍设置专门的索引。
2 我们索引书籍的 ID,以便可以对其进行投影(如下所示)。
3 我们使用与 Author 相同的 @FullTextField,但您会注意到分析器不同——稍后会详细介绍。
4 Author 一样,我们将一个构造函数标记为 @ProjectionConstructor,以便可以从索引内容中重建 Book 实例。

分析器和规范化器

简介

分析是全文搜索的重要组成部分:它定义了在索引或构建搜索查询时文本如何被处理。

分析器的作用是将文本拆分为 token(~单词)并过滤它们(例如,将其全部转换为小写并删除重音符号)。

规范化器是一种特殊的分析器,它将输入保留为单个 token。它对于排序或索引关键字特别有用。

有很多内置的分析器,但您也可以开发自己的分析器以满足您的特定需求。

您可以在 Elasticsearch 文档的 分析部分 中了解更多关于 Elasticsearch 分析框架的信息。

定义使用的分析器

当我们向实体添加 Hibernate Search 注解时,我们定义了使用的分析器和规范化器。通常

@FullTextField(analyzer = "english")
@FullTextField(analyzer = "name")
@KeywordField(name = "lastName_sort", sortable = Sortable.YES, normalizer = "sort")

我们使用

  • 一个名为 name 的分析器用于个人姓名,

  • 一个名为 english 的分析器用于书名,

  • 一个名为 sort 的规范化器用于排序字段

但我们还没有设置它们。

让我们看看如何使用 Hibernate Search 来实现它。

设置分析器

这是一项简单的任务,我们只需要创建一个 ElasticsearchAnalysisConfigurer 的实现(并配置 Quarkus 使用它,稍后会详细介绍)。

为了满足我们的要求,让我们创建以下实现

package org.acme.hibernate.search.elasticsearch.config;

import org.hibernate.search.backend.elasticsearch.analysis.ElasticsearchAnalysisConfigurationContext;
import org.hibernate.search.backend.elasticsearch.analysis.ElasticsearchAnalysisConfigurer;

import io.quarkus.hibernate.search.standalone.elasticsearch.SearchExtension;

@SearchExtension (1)
public class AnalysisConfigurer implements ElasticsearchAnalysisConfigurer {

    @Override
    public void configure(ElasticsearchAnalysisConfigurationContext context) {
        context.analyzer("name").custom() (2)
                .tokenizer("standard")
                .tokenFilters("asciifolding", "lowercase");

        context.analyzer("english").custom() (3)
                .tokenizer("standard")
                .tokenFilters("asciifolding", "lowercase", "porter_stem");

        context.normalizer("sort").custom() (4)
                .tokenFilters("asciifolding", "lowercase");
    }
}
1 @SearchExtension 限定符注解配置器实现,以告知 Quarkus 它应该用于 Hibernate Search Standalone,默认情况下用于所有 Elasticsearch 索引。

该注解还可以针对特定的持久化单元(@SearchExtension(persistenceUnit = "nameOfYourPU"))、后端(@SearchExtension(backend = "nameOfYourBackend"))、索引(@SearchExtension(index = "nameOfYourIndex"))或它们的组合(@SearchExtension(persistenceUnit = "nameOfYourPU", backend = "nameOfYourBackend", index = "nameOfYourIndex"))。

2 这是一个简单的分析器,它根据空格拆分单词,通过其 ASCII 对应项删除任何非 ASCII 字符(从而删除重音符号)并将所有内容转换为小写。在我们的示例中,它用于作者的姓名。
3 我们对这个分析器更具侵略性,它包含一些词干提取:我们将能够搜索 mystery 并获得结果,即使索引的输入包含 mysteries。对于人名来说,这显然过于激进,但对于书名来说却是完美的。
4 这是用于排序的规范化器。与我们的第一个分析器非常相似,只是我们不对单词进行分词,因为我们想要一个且只有一个 token。

有关配置分析器的更多信息,请参阅参考文档的 此部分

实现 REST 服务

创建 org.acme.hibernate.search.elasticsearch.LibraryResource

package org.acme.hibernate.search.elasticsearch;

import java.util.ArrayList;
import java.util.UUID;

import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.MediaType;

import org.acme.hibernate.search.elasticsearch.model.Author;
import org.acme.hibernate.search.elasticsearch.model.Book;

import org.hibernate.search.mapper.pojo.standalone.mapping.SearchMapping;
import org.hibernate.search.mapper.pojo.standalone.session.SearchSession;

import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.RestPath;

@Path("/library")
public class LibraryResource {

    @Inject
    SearchMapping searchMapping; (1)

    @PUT
    @Path("author")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public void addAuthor(@RestForm String firstName, @RestForm String lastName) {
        try (var searchSession = searchMapping.createSession()) { (2)
            Author author = new Author(UUID.randomUUID(), firstName, lastName, new ArrayList<>());
            searchSession.indexingPlan().add(author); (3)
        }
    }

    @GET
    @Path("author/{id}")
    public Author getAuthor(@RestPath UUID id) {
        try (var searchSession = searchMapping.createSession()) {
            return getAuthor(searchSession, id);
        }
    }

    private Author getAuthor(SearchSession searchSession, UUID id) {
        return searchSession.search(Author.class) (4)
                .where(f -> f.id().matching(id))
                .fetchSingleHit()
                .orElseThrow(NotFoundException::new);
    }

    @POST
    @Path("author/{id}")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public void updateAuthor(@RestPath UUID id, @RestForm String firstName, @RestForm String lastName) {
        try (var searchSession = searchMapping.createSession()) {
            Author author = getAuthor(searchSession, id); (5)
            author.firstName = firstName;
            author.lastName = lastName;
            searchSession.indexingPlan().addOrUpdate(author); (5)
        }
    }

    @DELETE
    @Path("author/{id}")
    public void deleteAuthor(@RestPath UUID id) {
        try (var searchSession = searchMapping.createSession()) {
            searchSession.indexingPlan().purge(Author.class, id, null); (6)
        }
    }

    @PUT
    @Path("author/{authorId}/book/")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public void addBook(@RestPath UUID authorId, @RestForm String title) {
        try (var searchSession = searchMapping.createSession()) {
            Author author = getAuthor(searchSession, authorId); (7)
            author.books.add(new Book(authorId, title));
            searchSession.indexingPlan().addOrUpdate(author);
        }
    }

    @DELETE
    @Path("author/{authorId}/book/{bookId}")
    public void deleteBook(@RestPath UUID authorId, @RestPath UUID bookId) {
        try (var searchSession = searchMapping.createSession()) {
            Author author = getAuthor(searchSession, authorId); (7)
            author.books.removeIf(book -> book.id.equals(bookId));
            searchSession.indexingPlan().addOrUpdate(author);
        }
    }
}
1 注入 Hibernate Search 映射,这是 Hibernate Search API 的主要入口点。
2 创建 Hibernate Search 会话,允许在索引上执行操作。
3 要索引新作者,请检索会话的索引计划并调用 add,将作者实例作为参数传入。
4 要从索引中检索作者,请执行简单的搜索——稍后将详细介绍——按标识符搜索。
5 要更新作者,请从索引中检索它,应用更改,检索会话的索引计划并调用 addOrUpdate,将作者实例作为参数传入。
6 要按标识符删除作者,请检索会话的索引计划并调用 purge,将作者类和标识符作为参数传入。
7 由于书籍由作者“拥有”(它们会为每个作者复制,并且它们的生命周期与作者绑定),因此添加/删除书籍只是对作者的更新。

这里没有什么突破性的:只是在 REST 服务中使用 Hibernate Search API 进行了一些 CRUD 操作。

有趣的部分在于添加了一个搜索端点。在我们的 LibraryResource 中,我们只需要添加以下方法(以及一些 import 语句)

    @GET
    @Path("author/search")
    public List<Author> searchAuthors(@RestQuery String pattern, (1)
            @RestQuery Optional<Integer> size) {
        try (var searchSession = searchMapping.createSession()) { (2)
            return searchSession.search(Author.class) (3)
                    .where(f -> pattern == null || pattern.isBlank()
                            ? f.matchAll() (4)
                            : f.simpleQueryString()
                                    .fields("firstName", "lastName", "books.title").matching(pattern)) (5)
                    .sort(f -> f.field("lastName_sort").then().field("firstName_sort")) (6)
                    .fetchHits(size.orElse(20)); (7)
        }
    }
1 使用 org.jboss.resteasy.reactive.RestQuery 注解类型来避免重复参数名。
2 创建 Hibernate Search 会话,允许在索引上执行操作。
3 我们指示我们正在搜索 Author
4 我们创建一个谓词:如果模式为空,我们使用 matchAll() 谓词。
5 如果我们有一个有效的模式,我们将创建一个 simpleQueryString() 谓词,作用于 firstNamelastNamebooks.title 字段,以匹配我们的模式。
6 我们定义了结果的排序顺序。这里我们按姓氏排序,然后按名字排序。请注意,我们使用了为排序创建的特定字段。
7 获取 size 个热门命中,默认为 20。显然,也支持分页。

Hibernate Search DSL 支持 Elasticsearch 谓词的很大一部分(match、range、nested、phrase、spatial 等)。可以自由使用自动补全来探索 DSL。

当这还不够时,您始终可以 直接使用 JSON 定义谓词

自动数据初始化

为了演示目的,让我们导入初始数据集。

让我们在 LibraryResource 中添加一些方法

    void onStart(@Observes StartupEvent ev) { (1)
        // Index some test data if nothing exists
        try (var searchSession = searchMapping.createSession()) {
            if (0 < searchSession.search(Author.class) (2)
                    .where(f -> f.matchAll())
                    .fetchTotalHitCount()) {
                return;
            }
            for (Author author : initialDataSet()) { (3)
                searchSession.indexingPlan().add(author); (4)
            }
        }
    }

    private List<Author> initialDataSet() {
        return List.of(
                new Author(UUID.randomUUID(), "John", "Irving",
                        List.of(
                                new Book(UUID.randomUUID(), "The World According to Garp"),
                                new Book(UUID.randomUUID(), "The Hotel New Hampshire"),
                                new Book(UUID.randomUUID(), "The Cider House Rules"),
                                new Book(UUID.randomUUID(), "A Prayer for Owen Meany"),
                                new Book(UUID.randomUUID(), "Last Night in Twisted River"),
                                new Book(UUID.randomUUID(), "In One Person"),
                                new Book(UUID.randomUUID(), "Avenue of Mysteries"))),
                new Author(UUID.randomUUID(), "Paul", "Auster",
                        List.of(
                                new Book(UUID.randomUUID(), "The New York Trilogy"),
                                new Book(UUID.randomUUID(), "Mr. Vertigo"),
                                new Book(UUID.randomUUID(), "The Brooklyn Follies"),
                                new Book(UUID.randomUUID(), "Invisible"),
                                new Book(UUID.randomUUID(), "Sunset Park"),
                                new Book(UUID.randomUUID(), "4 3 2 1"))));
    }
1 添加一个将在应用程序启动时执行的方法。
2 检查索引中是否已存在数据——如果不存在,则退出。
3 生成初始数据集。
4 对于每个作者,将其添加到索引中。

配置应用程序

与往常一样,我们可以在 Quarkus 配置文件 application.properties 中配置所有内容。

编辑 src/main/resources/application.properties 并注入以下配置

quarkus.hibernate-search-standalone.mapping.structure=document (1)
quarkus.hibernate-search-standalone.elasticsearch.version=9 (2)
quarkus.hibernate-search-standalone.indexing.plan.synchronization.strategy=sync (3)

%prod.quarkus.hibernate-search-standalone.elasticsearch.hosts=localhost:9200 (4)
1 我们需要告知 Hibernate Search 实体的结构。

在此应用程序中,我们将索引实体(作者)视为“文档”的根:作者“拥有”其通过关联引用的书籍,这些书籍*不能*独立于作者进行更新。

有关其他选项和更多详细信息,请参阅 quarkus.hibernate-search-standalone.mapping.structure

2 我们需要告知 Hibernate Search 我们将使用的 Elasticsearch 版本。

这很重要,因为 Elasticsearch 映射语法因版本而异。由于映射是在构建时创建以减少启动时间,因此 Hibernate Search 无法连接到集群来自动检测版本。请注意,对于 OpenSearch,您需要将版本前缀为 opensearch:;请参阅 OpenSearch 兼容性

3 这意味着我们在完成写入之前等待实体可搜索。在生产环境中,write-sync 默认值将提供更好的性能。使用 sync 对于测试尤其重要,因为您需要实体立即可搜索。
4 对于开发和测试,我们依赖 Dev Services,这意味着 Quarkus 将自动启动一个 Elasticsearch 集群。但在生产模式下,我们将希望手动启动一个 Elasticsearch 集群,这就是为什么我们在 prod 配置文件(%prod. 前缀)中为 Quarkus 提供此连接信息。

由于我们依赖 Dev Services,Elasticsearch 模式将在每次应用程序启动时(在测试和开发模式下)自动删除并重新创建(除非已显式设置 quarkus.hibernate-search-standalone.schema-management.strategy)。

如果您出于某种原因无法使用 Dev Services,您将需要设置以下属性以获得类似的行为

%dev,test.quarkus.hibernate-search-standalone.schema-management.strategy=drop-and-create
有关 Hibernate Search Standalone 扩展配置的更多信息,请参阅 配置参考

创建一个前端

现在让我们添加一个简单的网页来与我们的 LibraryResource 进行交互。Quarkus 会自动提供位于 META-INF/resources 目录下的静态资源。在 src/main/resources/META-INF/resources 目录中,用此 index.html 文件中的内容覆盖现有的 index.html 文件。

准备好玩您的应用程序

您现在可以与您的 REST 服务交互

  • 使用以下命令启动您的 Quarkus 应用程序

    CLI
    quarkus dev
    Maven
    ./mvnw quarkus:dev
    Gradle
    ./gradlew --console=plain quarkusDev
  • 在浏览器中打开 https://:8080/

  • 搜索作者或书名(我们已经为您初始化了一些数据)

  • 创建新的作者和书籍,并搜索它们

如您所见,您的所有更新都会自动同步到 Elasticsearch 集群。

构建本机可执行文件

您可以使用常用命令构建本机可执行文件

CLI
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

与原生可执行文件编译一样,此操作会消耗大量内存。

在构建原生可执行文件时停止这两个容器,并在完成后再次启动它们可能会更安全。

运行它就像执行 ./target/hibernate-search-standalone-elasticsearch-quickstart-1.0.0-SNAPSHOT-runner 一样简单。

然后,您可以将浏览器指向 https://:8080/ 并使用您的应用程序。

启动速度比平时稍慢:这主要是因为我们在每次启动时都会删除并重新创建 Elasticsearch 映射。我们还索引了一些初始数据。

在实际应用程序中,这显然不是您每次启动都会做的事情。

Dev Services(无配置数据存储)

Quarkus 支持一项称为 Dev Services 的功能,该功能允许您启动各种容器而无需任何配置。

对于 Elasticsearch,此支持扩展到默认的 Elasticsearch 连接。实际这意味着,如果您未配置 quarkus.hibernate-search-standalone.elasticsearch.hosts,Quarkus 将在运行测试或在 开发模式 下自动启动 Elasticsearch 容器,并自动配置连接。

运行应用程序的生产版本时,需要像往常一样配置 Elasticsearch 连接,因此如果您想在 application.properties 中包含生产数据库配置并继续使用 Dev Services,我们建议您使用 %prod. 配置文件来定义您的 Elasticsearch 设置。

Elasticsearch 的 Dev Services 目前无法同时启动多个集群,因此它只能与默认持久化单元的默认后端一起使用:命名的持久化单元或命名的后端将无法利用 Elasticsearch 的 Dev Services。

有关更多信息,您可以阅读 Elasticsearch 开发服务指南

程序化映射

如果由于某种原因无法将 Hibernate Search 注解添加到实体,则可以改用程序化映射。程序化映射是通过通过映射配置器(HibernateOrmSearchMappingConfigurer)公开的 ProgrammaticMappingConfigurationContext 进行配置的。

映射配置器(StandalonePojoMappingConfigurer)提供的功能远不止程序化映射。它还允许 配置注解映射、桥接等

以下是一个应用了程序化映射的映射配置器示例

package org.acme.hibernate.search.elasticsearch.config;

import org.hibernate.search.mapper.pojo.standalone.mapping.StandalonePojoMappingConfigurationContext;
import org.hibernate.search.mapper.pojo.standalone.mapping.StandalonePojoMappingConfigurer;
import org.hibernate.search.mapper.pojo.mapping.definition.programmatic.TypeMappingStep;

import io.quarkus.hibernate.search.standalone.elasticsearch.SearchExtension;

@SearchExtension (1)
public class CustomMappingConfigurer implements StandalonePojoMappingConfigurer {

	@Override
    public void configure(StandalonePojoMappingConfigurationContext context) {
        TypeMappingStep type = context.programmaticMapping()    (2)
                .type(SomeIndexedEntity.class);                 (3)
        type.searchEntity();                                    (4)
        type.indexed()                                          (5)
                .index(SomeIndexedEntity.INDEX_NAME);           (6)
        type.property("id").documentId();                       (7)
        type.property("text").fullTextField();                  (8)
    }
}
1 @SearchExtension 限定符注解配置器实现,以告知 Quarkus 它应该被 Hibernate Search Standalone 使用。
2 访问程序化映射上下文。
3 SomeIndexedEntity 类型创建映射步骤。
4 SomeIndexedEntity 定义为 Hibernate Search 的实体类型。
5 SomeIndexedEntity 实体定义为已索引。
6 提供要为 SomeIndexedEntity 实体使用的索引名称。
7 定义文档 ID 属性。
8 text 属性定义一个全文搜索字段。

OpenSearch 兼容性

quarkus.hibernate-search-standalone.elasticsearch.version=opensearch:3.0

所有其他配置选项和 API 与 Elasticsearch 完全相同。

您可以在 Hibernate Search 的参考文档的 此部分 中找到有关兼容的 Elasticsearch 发行版和版本的更多信息。

CDI 集成

注入入口点

您可以使用 CDI 注入 Hibernate Search 的主要入口点 SearchMapping

@Inject
SearchMapping searchMapping;

插入自定义组件

Hibernate Search Standalone 的 Quarkus 扩展将自动将带有 @SearchExtension 注解的组件注入到 Hibernate Search 中。

该注解可以选择性地针对特定的后端(@SearchExtension(backend = "nameOfYourBackend"))、索引(@SearchExtension(index = "nameOfYourIndex"))或它们的组合(@SearchExtension(backend = "nameOfYourBackend", index = "nameOfYourIndex")),当它对注入的组件类型有意义时。

此功能可用于以下组件类型

org.hibernate.search.engine.reporting.FailureHandler

一个组件,应被通知后台进程(主要是索引操作)中发生的任何故障。

范围:每个应用程序一个。

有关更多信息,请参阅参考文档的这一部分

org.hibernate.search.mapper.pojo.standalone.mapping.StandalonePojoMappingConfigurer

一个用于配置 Hibernate Search 映射的组件,特别是程序化配置。

范围:每个持久化单元一个或多个。

有关更多信息,请参阅 本指南的此部分

org.hibernate.search.mapper.pojo.work.IndexingPlanSynchronizationStrategy

一个用于配置应用程序线程和索引之间如何同步的组件。

范围:每个应用程序一个。

有关更多信息,请参阅参考文档的这一部分

org.hibernate.search.backend.elasticsearch.analysis.ElasticsearchAnalysisConfigurer

一个用于配置全文分析(例如,分析器、规范化器)的组件。

范围:每个后端一个或多个。

有关更多信息,请参阅 本指南的此部分

org.hibernate.search.backend.elasticsearch.index.layout.IndexLayoutStrategy

一个用于配置 Elasticsearch 布局的组件:索引名称、索引别名……

范围:每个后端一个。

有关更多信息,请参阅参考文档的此章节

离线启动

默认情况下,Hibernate Search 在启动时会向 Elasticsearch 集群发送一些请求。如果 Elasticsearch 集群在 Hibernate Search 启动时并非一定处于运行状态,这可能会导致启动失败。

为了解决这个问题,您可以配置 Hibernate Search 在启动时不要发送任何请求

当然,即使有此配置,在 Elasticsearch 集群变得可访问之前,Hibernate Search 仍然无法索引任何内容或运行搜索查询。

如果您通过将 quarkus.hibernate-search-standalone.schema-management.strategy 设置为 none 来禁用自动模式创建,您将不得不在应用程序开始持久化/更新实体和执行搜索请求之前手动创建模式。

有关更多信息,请参阅参考文档的 此部分

加载

作为使用 Elasticsearch 作为主要数据存储的替代方法,此扩展还可以用于索引来自其他数据存储的实体。

在这种情况下,您需要将 quarkus.hibernate-search-standalone.mapping.structure 设置为与要索引的应用程序模型结构匹配的值。

为此,需要从其他数据存储加载实体,并且必须显式实现这种加载。

您可以参考 Hibernate Search 的参考文档以获取有关配置加载的更多信息

  • 要从外部数据源加载实体以重新索引它们,请参阅 批量加载策略

  • 要在返回搜索命中时从外部数据源加载实体,请参阅 选择加载策略

在 Quarkus 中,Hibernate Search 参考文档中提到的实体加载器可以定义为 CDI bean,但仍然需要使用 @SearchEntity(loadingBinder = …​) 将其附加到特定实体。

管理端点

Hibernate Search 的管理端点是预览版。

预览版中,向后兼容性和在生态系统中的存在性不受保证。特定改进可能需要更改配置或 API,甚至存储格式,并且正在计划成为稳定版。欢迎在我们的 邮件列表 或我们的 GitHub 问题跟踪器 中提出问题。

Hibernate Search 扩展提供了一个 HTTP 端点,用于通过 管理界面 重新索引数据。默认情况下,此端点不可用。可以通过配置属性启用它,如下所示。

quarkus.management.enabled=true (1)
quarkus.hibernate-search-standalone.management.enabled=true (2)
1 启用 管理界面
2 启用 Hibernate Search Standalone 特定的管理端点。

启用管理端点后,可以通过 /q/hibernate-search/standalone/reindex 重新索引数据,其中 /q 是默认的管理根路径,/hibernate-search/standalone/ 是默认的 Hibernate Search 根管理路径。它可以(/hibernate-search/standalone/)通过配置属性更改,如下所示。

quarkus.hibernate-search-standalone.management.root-path=custom-root-path (1)
1 为 Hibernate Search 的管理端点使用自定义的 custom-root-path 路径。如果使用默认管理根路径,则重新索引路径将变为 /q/custom-root-path/reindex

此端点仅接受 POST 请求,且 application/json 内容类型。如果提交了空请求体,将重新索引所有索引实体。

要重新索引实体类型,需要将其配置为从外部源加载

没有该配置,通过管理端点(或任何其他 API)进行的重新索引将失败。

如果只需要重新索引部分实体,或者需要自定义底层批量索引器的配置,则可以通过请求体传递此信息,如下所示。

{
  "filter": {
    "types": ["EntityName1", "EntityName2", "EntityName3", ...], (1)
  },
  "massIndexer":{
    "typesToIndexInParallel": 1, (2)
  }
}
1 一组要重新索引的实体名称。如果未指定或为空,将重新索引所有实体类型。
2 设置并行索引的实体类型数量。

下面示例中列出了所有可能的过滤器和可用的批量索引器配置。

{
  "filter": { (1)
    "types": ["EntityName1", "EntityName2", "EntityName3", ...], (2)
    "tenants": ["tenant1", "tenant2", ...] (3)
  },
  "massIndexer":{ (4)
    "typesToIndexInParallel": 1, (5)
    "threadsToLoadObjects": 6,  (6)
    "batchSizeToLoadObjects": 10, (7)
    "cacheMode": "IGNORE", (8)
    "mergeSegmentsOnFinish": false, (9)
    "mergeSegmentsAfterPurge": true, (10)
    "dropAndCreateSchemaOnStart": false, (11)
    "purgeAllOnStart": true, (12)
    "idFetchSize": 100, (13)
    "transactionTimeout": 100000, (14)
  }
}
1 用于限制重新索引范围的过滤器对象。
2 一组要重新索引的实体名称。如果未指定或为空,将重新索引所有实体类型。
3 一个租户 ID 数组,用于多租户场景。如果未指定或为空,将重新索引所有租户。
4 批量索引器配置对象。
5 设置并行索引的实体类型数量。
6 设置用于加载根实体的线程数。
7 设置用于加载根实体的批量大小。
8 设置数据加载任务的缓存交互模式。
9 索引完成后,每个索引是否合并为单个段。
10 在初始索引清除之后、索引之前,每个索引是否合并为单个段。
11 在索引之前,是否删除索引及其模式(如果存在)。
12 在索引之前,是否从索引中删除所有实体。
13 指定加载主键时要使用的获取大小(如果对象需要被索引)。
14 指定用于加载 ID 和要重新索引的实体事务的超时时间。

请注意,JSON 中的所有属性都是可选的,并且只需要使用需要的属性。

有关批量索引器配置的更多详细信息,请参阅 Hibernate Search 参考文档的 相应部分

提交重新索引请求将触发后台索引。批量索引进度将显示在应用程序日志中。为了测试目的,了解索引何时完成可能很有用。在 URL 中添加 wait_for=finished 查询参数将导致管理端点返回一个分块响应,该响应将报告索引何时开始以及何时完成。

限制

进一步阅读

如果您有兴趣了解更多关于 Hibernate Search 的信息,Hibernate 团队会发布 详尽的参考文档,以及一个列出 其他相关资源 的页面。

常见问题解答

为什么只支持 Elasticsearch?

Hibernate Search 支持 Lucene 后端和 Elasticsearch 后端。

在 Quarkus 的背景下,为了构建可扩展的应用程序,我们认为后者更有意义。因此,我们集中精力于它。

目前我们不打算在 Quarkus 中支持 Lucene 后端,尽管 Quarkiverse 中有一个跟踪此类实现进度的 issue:quarkiverse/quarkus-hibernate-search-extras#180

Hibernate Search Standalone 配置参考

构建时固定的配置属性 - 所有其他配置属性都可以在运行时覆盖

配置属性

类型

默认

是否在*构建期间*启用了 Hibernate Search Standalone。

如果在构建期间禁用了 Hibernate Search,所有与 Hibernate Search 相关的处理都将被跳过,但无法在运行时激活 Hibernate Search:quarkus.hibernate-search-standalone.active 将默认为 false,将其设置为 true 将导致错误。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ENABLED

显示更多

布尔值

true

一个bean 引用,指向应被通知后台进程(主要是索引操作)中发生的任何故障的组件。

引用的 bean 必须实现 FailureHandler

有关更多信息,请参阅参考文档的这一部分

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 FailureHandler 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。有关更多信息,请参阅 本节

如果设置了此配置属性,它将优先于任何 @SearchExtension 注释。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_BACKGROUND_FAILURE_HANDLER

显示更多

字符串

一个或多个bean 引用,指向用于配置 Hibernate Search 映射的组件,特别是程序化配置。

引用的 bean 必须实现 StandalonePojoMappingConfigurer

有关如何使用映射配置器应用程序化映射的示例,请参阅 程序化映射

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 StandalonePojoMappingConfigurer 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。有关更多信息,请参阅 本节

如果设置了此配置属性,它将优先于任何 @SearchExtension 注释。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_MAPPING_CONFIGURER

显示更多

字符串列表

Hibernate Search 实体映射的结构。

这必须与使用 Hibernate Search 索引的应用程序模型结构相匹配

graph(默认)

通过 Hibernate Search 索引的实体是实体图中的节点,即索引实体独立于它通过关联引用的其他实体,这些其他实体*可以*独立于索引实体进行更新。

实体之间的关联必须是双向的:通过 @AssociationInverseSide 指定关联的反向侧是*必需*的,除非通过 @IndexingDependency(reindexOnUpdate = …​) 为该关联禁用重新索引。

document

通过 Hibernate Search 索引的实体是文档的根,即索引实体“拥有”它通过关联引用的其他实体,这些其他实体*不能*独立于索引实体进行更新。

实体之间的关联可以是单向的:通过 @AssociationInverseSide 指定关联的反向侧*不是必需*的。

另请参阅 @AssociationInverseSide@IndexingDependency(reindexOnUpdate = …​)@AssociationInverseSide@IndexingDependency(reindexOnUpdate = …​)

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_MAPPING_STRUCTURE

显示更多

graph(实体通过 Hibernate Search 索引是实体图中的节点。在这种结构下:* 索引实体独立于它通过关联引用的其他实体,这些实体*可以*独立于索引实体进行更新;特别是它们可以传递给 {@link org.hibernate.search.mapper.pojo.standalone.work.SearchIndexingPlan#addOrUpdate(Object)}。* 因此,当实体发生更改时,Hibernate Search 可能需要解析其他实体以重新索引,这意味着特别是实体之间的关联必须是双向的:通过 @AssociationInverseSide 指定关联的反向侧是*必需*的,除非通过 @IndexingDependency(reindexOnUpdate = …​) 为该关联禁用重新索引。另请参阅 link\:https://docs.jboss.com.cn/hibernate/search/8.0/reference/en-US/html_single/#mapping-reindexing-associationinverseside\]@AssociationInverseSide] link\:https://docs.jboss.com.cn/hibernate/search/8.0/reference/en-US/html_single/#mapping-reindexing-reindexonupdate\]@IndexingDependency(reindexOnUpdate = …​)]。,document(实体通过 Hibernate Search 索引是文档的根。在这种结构下:* 索引实体“拥有”它通过关联引用的其他实体,这些实体*不能*独立于索引实体进行更新;特别是它们不能传递给 {@link org.hibernate.search.mapper.pojo.standalone.work.SearchIndexingPlan#addOrUpdate(Object)}。* 因此,当实体发生更改时,Hibernate Search 不需要解析其他实体以重新索引,这意味着特别是实体之间的关联可以是单向的:通过 @AssociationInverseSide 指定关联的反向侧*不是必需*的。另请参阅 link\:https://docs.jboss.com.cn/hibernate/search/8.0/reference/en-US/html_single/#mapping-reindexing-associationinverseside\]@AssociationInverseSide]。

graph(实体通过 Hibernate Search 索引是实体图中的节点。在这种结构下:* 索引实体独立于它通过关联引用的其他实体,这些实体*可以*独立于索引实体进行更新;特别是它们可以传递给 {@link org.hibernate.search.mapper.pojo.standalone.work.SearchIndexingPlan#addOrUpdate(Object)}。* 因此,当实体发生更改时,Hibernate Search 可能需要解析其他实体以重新索引,这意味着特别是实体之间的关联必须是双向的:通过 @AssociationInverseSide 指定关联的反向侧是*必需*的,除非通过 @IndexingDependency(reindexOnUpdate = …​) 为该关联禁用重新索引。另请参阅 link\:https://docs.jboss.com.cn/hibernate/search/8.0/reference/en-US/html_single/#mapping-reindexing-associationinverseside\]@AssociationInverseSide] link\:https://docs.jboss.com.cn/hibernate/search/8.0/reference/en-US/html_single/#mapping-reindexing-reindexonupdate\]@IndexingDependency(reindexOnUpdate = …​)]。

Hibernate Search Standalone 在运行时是否应激活。

如果 Hibernate Search Standalone 未激活,它将不会随应用程序启动,并且访问 SearchMapping 进行搜索或其他操作将不可行。

请注意,如果 Hibernate Search Standalone 被禁用(即 quarkus.hibernate-search-standalone.enabled 设置为 false),它将不会激活,并且将此属性设置为 true 将导致失败。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ACTIVE

显示更多

布尔值

'true' 表示 Hibernate Search Standalone 已激活;否则为 'false'

模式管理策略,控制如何在启动和关闭时创建、更新、验证或删除索引及其模式。

可用值

策略

定义

none

什么都不做:假设索引已经存在,并且它们的模式与 Hibernate Search 的期望匹配。

validate

验证索引是否存在以及它们的模式是否与 Hibernate Search 的期望匹配。

如果不是,则抛出异常,但不尝试解决问题。

create

对于不存在的索引,创建它们以及它们的模式。

对于已经存在的索引,什么都不做:假设它们的模式与 Hibernate Search 的期望匹配。

create-or-validate(默认,除非使用 Dev Services)

对于不存在的索引,创建它们以及它们的模式。

对于已经存在的索引,验证它们的模式是否与 Hibernate Search 的期望匹配。

如果不是,则抛出异常,但不尝试解决问题。

create-or-update

对于不存在的索引,创建它们以及它们的模式。

对于已经存在的索引,验证它们的模式是否与 Hibernate Search 的期望匹配; 如果不匹配期望,则尝试更新它。

此策略不适合生产环境,由于几个重要的限制,但在开发时可能很有用。

drop-and-create

对于不存在的索引,创建它们以及它们的模式。

对于已经存在的索引,删除它们,然后创建它们以及它们的模式。

drop-and-create-and-drop(使用 Dev Services 时默认

对于不存在的索引,创建它们以及它们的模式。

对于已经存在的索引,删除它们,然后创建它们以及它们的模式。

此外,在关闭时删除索引及其模式。

有关更多信息,请参阅参考文档的 此部分

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_SCHEMA_MANAGEMENT_STRATEGY

显示更多

none, validate, create, create-or-validate, create-or-update, drop-and-create, drop-and-create-and-drop

使用 Dev Services 时为 drop-and-create-and-drop; 否则为 create-or-validate

如何在应用程序线程和索引之间进行同步,尤其是在依赖于实体更改时(隐式)侦听器触发的索引,以及在使用显式的 SearchIndexingPlan 时。

定义在 SearchSession 关闭后,索引完成的程度,以便恢复应用程序线程。

可用值

策略

吞吐量

应用程序线程恢复时的保证

应用的更改

防止崩溃/断电的更改

搜索中可见的更改

async

最佳

write-sync(默认

中等

read-sync

中等到最差

sync

最差

此属性还接受一个bean 引用,指向 IndexingPlanSynchronizationStrategy 的自定义实现。

有关更多信息,请参阅参考文档的这一部分

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 IndexingPlanSynchronizationStrategy 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。如果设置了此配置属性,它将优先于任何 @SearchExtension 注解。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_INDEXING_PLAN_SYNCHRONIZATION_STRATEGY

显示更多

字符串

write-sync

Elasticsearch/OpenSearch 后端配置

类型

默认

quarkus.hibernate-search-standalone.elasticsearch."backend-name".version

集群中使用的 Elasticsearch 版本。

由于 schema 是在没有连接到服务器的情况下生成的,因此此项是必需的。

它不必是精确的版本(例如,它可以是 77.1),但它必须足够精确以选择一个与协议方言(用于与 Elasticsearch 通信的方言)兼容的模型方言。

这里没有经验法则,因为它取决于 Elasticsearch 版本引入的 schema 不兼容性。无论如何,如果出现问题,当 Hibernate Search 尝试连接到集群时,您将收到错误。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_VERSION

显示更多

ElasticsearchVersion

quarkus.hibernate-search-standalone.elasticsearch."backend-name".schema-management.settings-file

classpath 中文件的路径,该文件包含自定义索引设置,以便在创建 Elasticsearch 索引时包含在索引定义中。

提供的设置将与 Hibernate Search 生成的设置合并,包括分析器定义。当通过分析器配置器和这些自定义设置配置分析时,行为是未定义的;不应依赖它。

有关更多信息,请参阅参考文档的此章节

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_SCHEMA_MANAGEMENT_SETTINGS_FILE

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".schema-management.mapping-file

classpath 中文件的路径,该文件包含自定义索引映射,以便在创建 Elasticsearch 索引时包含在索引定义中。

该文件不需要(通常也不应该)包含完整的映射:Hibernate Search 将自动在给定的映射中注入缺失的属性(索引字段)。

有关更多信息,请参阅参考文档的此章节

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_SCHEMA_MANAGEMENT_MAPPING_FILE

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".analysis.configurer

一个或多个bean 引用,用于配置全文分析(例如,分析器、规范化器)的组件。

引用的 Bean 必须实现 ElasticsearchAnalysisConfigurer

有关更多信息,请参阅 设置分析器

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 ElasticsearchAnalysisConfigurer 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。有关更多信息,请参阅 本节

如果设置了此配置属性,它将优先于任何 @SearchExtension 注释。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_ANALYSIS_CONFIGURER

显示更多

字符串列表

quarkus.hibernate-search-standalone.elasticsearch."backend-name".hosts

Elasticsearch 服务器的主机列表。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_HOSTS

显示更多

字符串列表

localhost:9200

quarkus.hibernate-search-standalone.elasticsearch."backend-name".protocol

联系 Elasticsearch 服务器时使用的协议。 设置为 "https" 以启用 SSL/TLS。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_PROTOCOL

显示更多

http(使用明文 HTTP,禁用 SSL/TLS。),https(使用 HTTPS,启用 SSL/TLS。)

http使用明文 HTTP,禁用 SSL/TLS。

quarkus.hibernate-search-standalone.elasticsearch."backend-name".username

用于身份验证的用户名。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_USERNAME

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".password

用于身份验证的密码。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_PASSWORD

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".connection-timeout

建立与 Elasticsearch 服务器的连接时的超时时间。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_CONNECTION_TIMEOUT

显示更多

Duration 

1S

quarkus.hibernate-search-standalone.elasticsearch."backend-name".read-timeout

从 Elasticsearch 服务器读取响应时的超时时间。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_READ_TIMEOUT

显示更多

Duration 

30S

quarkus.hibernate-search-standalone.elasticsearch."backend-name".request-timeout

执行对 Elasticsearch 服务器的请求时的超时时间。

这包括等待连接可用、发送请求和读取响应所需的时间。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_REQUEST_TIMEOUT

显示更多

Duration 

quarkus.hibernate-search-standalone.elasticsearch."backend-name".max-connections

到所有 Elasticsearch 服务器的最大连接数。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_MAX_CONNECTIONS

显示更多

整数

20

quarkus.hibernate-search-standalone.elasticsearch."backend-name".max-connections-per-route

每个 Elasticsearch 服务器的最大连接数。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_MAX_CONNECTIONS_PER_ROUTE

显示更多

整数

10

quarkus.hibernate-search-standalone.elasticsearch."backend-name".discovery.enabled

定义是否启用自动发现。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_DISCOVERY_ENABLED

显示更多

布尔值

false

quarkus.hibernate-search-standalone.elasticsearch."backend-name".discovery.refresh-interval

节点列表的刷新间隔。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_DISCOVERY_REFRESH_INTERVAL

显示更多

Duration 

10S

quarkus.hibernate-search-standalone.elasticsearch."backend-name".thread-pool.size

分配给后端的线程池的大小。

请注意,该数字是每个后端,而不是每个索引。添加更多索引不会添加更多线程。

由于此线程池中发生的所有操作都是非阻塞的,将大小增加到 JVM 可用的处理器核心数以上不会带来明显性能提升。唯一需要更改此设置的原因是减少线程数;例如,在一个具有单个索引和单个索引队列、运行在具有 64 个处理器核心的机器上的应用程序中,您可能希望减少线程数。

默认为启动时 JVM 可用的处理器核心数。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_THREAD_POOL_SIZE

显示更多

整数

quarkus.hibernate-search-standalone.elasticsearch."backend-name".query.shard-failure.ignore

是否忽略部分分片故障 (true) 或导致 Hibernate Search 引发异常 (false)。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_QUERY_SHARD_FAILURE_IGNORE

显示更多

布尔值

false

quarkus.hibernate-search-standalone.elasticsearch."backend-name".version-check.enabled

Hibernate Search 是否应在启动时检查 Elasticsearch 集群的版本。

如果 Elasticsearch 集群在启动时可能不可用,请设置为 false

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_VERSION_CHECK_ENABLED

显示更多

布尔值

true

quarkus.hibernate-search-standalone.elasticsearch."backend-name".schema-management.required-status

启动时所需的最小Elasticsearch 集群状态

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_SCHEMA_MANAGEMENT_REQUIRED_STATUS

显示更多

green, yellow, red

yellow

quarkus.hibernate-search-standalone.elasticsearch."backend-name".schema-management.required-status-wait-timeout

在引导失败之前,我们应该等待状态多长时间。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_SCHEMA_MANAGEMENT_REQUIRED_STATUS_WAIT_TIMEOUT

显示更多

Duration 

10S

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexing.queue-count

分配给每个索引的索引队列数。

更高的值将导致更多连接并行使用,这可能提高索引吞吐量,但有使 Elasticsearch 过载的风险,即溢出其 HTTP 请求缓冲区并触发断路器,导致 Elasticsearch 放弃某些请求并导致索引失败。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXING_QUEUE_COUNT

显示更多

整数

10

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexing.queue-size

索引队列的大小。

较低的值可能导致内存使用量减少,尤其是在有许多队列的情况下,但值太低会降低达到最大批量大小的可能性,并增加应用程序线程因队列已满而阻塞的可能性,这可能导致索引吞吐量降低。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXING_QUEUE_SIZE

显示更多

整数

1000

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexing.max-bulk-size

处理索引队列时创建的批量请求的最大大小。

更高的值将导致每次发送到 Elasticsearch 的 HTTP 请求中包含更多文档,这可能提高索引吞吐量,但有使 Elasticsearch 过载的风险,即溢出其 HTTP 请求缓冲区并触发断路器,导致 Elasticsearch 放弃某些请求并导致索引失败。

请注意,将此数字提高到队列大小以上没有效果,因为批量请求不能包含比队列中包含的请求更多的请求。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXING_MAX_BULK_SIZE

显示更多

整数

100

quarkus.hibernate-search-standalone.elasticsearch."backend-name".layout.strategy

一个bean 引用,用于配置 Elasticsearch 布局:索引名称、索引别名……

引用的 Bean 必须实现 IndexLayoutStrategy

可用的内置实现

simple

默认的、面向未来的策略:如果 Hibernate Search 中的索引名称是 myIndex,此策略将创建一个名为 myindex-000001 的索引,一个用于写入操作的别名,名为 myindex-write,以及一个用于读取操作的别名,名为 myindex-read

no-alias

一种没有索引别名的策略,主要在旧版集群上很有用:如果在 Hibernate Search 中的索引名称是 myIndex,则此策略将创建一个名为 myindex 的索引,并且不会使用任何别名。

有关更多信息,请参阅参考文档的此章节

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 IndexLayoutStrategy 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。有关更多信息,请参阅 本节

如果设置了此配置属性,它将优先于任何 @SearchExtension 注释。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_LAYOUT_STRATEGY

显示更多

字符串

每个索引的配置覆盖

类型

默认

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".schema-management.settings-file

classpath 中文件的路径,该文件包含自定义索引设置,以便在创建 Elasticsearch 索引时包含在索引定义中。

提供的设置将与 Hibernate Search 生成的设置合并,包括分析器定义。当通过分析器配置器和这些自定义设置配置分析时,行为是未定义的;不应依赖它。

有关更多信息,请参阅参考文档的此章节

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__SCHEMA_MANAGEMENT_SETTINGS_FILE

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".schema-management.mapping-file

classpath 中文件的路径,该文件包含自定义索引映射,以便在创建 Elasticsearch 索引时包含在索引定义中。

该文件不需要(通常也不应该)包含完整的映射:Hibernate Search 将自动在给定的映射中注入缺失的属性(索引字段)。

有关更多信息,请参阅参考文档的此章节

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__SCHEMA_MANAGEMENT_MAPPING_FILE

显示更多

字符串

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".analysis.configurer

一个或多个bean 引用,用于配置全文分析(例如,分析器、规范化器)的组件。

引用的 Bean 必须实现 ElasticsearchAnalysisConfigurer

有关更多信息,请参阅 设置分析器

与其设置此配置属性,不如简单地用 @SearchExtension 注解您的自定义 ElasticsearchAnalysisConfigurer 实现,并保持配置属性未设置:Hibernate Search 将自动使用带注解的实现。有关更多信息,请参阅 本节

如果设置了此配置属性,它将优先于任何 @SearchExtension 注释。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__ANALYSIS_CONFIGURER

显示更多

字符串列表

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".schema-management.required-status

启动时所需的最小Elasticsearch 集群状态

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__SCHEMA_MANAGEMENT_REQUIRED_STATUS

显示更多

green, yellow, red

yellow

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".schema-management.required-status-wait-timeout

在引导失败之前,我们应该等待状态多长时间。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__SCHEMA_MANAGEMENT_REQUIRED_STATUS_WAIT_TIMEOUT

显示更多

Duration 

10S

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".indexing.queue-count

分配给每个索引的索引队列数。

更高的值将导致更多连接并行使用,这可能提高索引吞吐量,但有使 Elasticsearch 过载的风险,即溢出其 HTTP 请求缓冲区并触发断路器,导致 Elasticsearch 放弃某些请求并导致索引失败。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__INDEXING_QUEUE_COUNT

显示更多

整数

10

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".indexing.queue-size

索引队列的大小。

较低的值可能导致内存使用量减少,尤其是在有许多队列的情况下,但值太低会降低达到最大批量大小的可能性,并增加应用程序线程因队列已满而阻塞的可能性,这可能导致索引吞吐量降低。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__INDEXING_QUEUE_SIZE

显示更多

整数

1000

quarkus.hibernate-search-standalone.elasticsearch."backend-name".indexes."index-name".indexing.max-bulk-size

处理索引队列时创建的批量请求的最大大小。

更高的值将导致每次发送到 Elasticsearch 的 HTTP 请求中包含更多文档,这可能提高索引吞吐量,但有使 Elasticsearch 过载的风险,即溢出其 HTTP 请求缓冲区并触发断路器,导致 Elasticsearch 放弃某些请求并导致索引失败。

请注意,将此数字提高到队列大小以上没有效果,因为批量请求不能包含比队列中包含的请求更多的请求。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_ELASTICSEARCH_INDEXES__INDEX_NAME__INDEXING_MAX_BULK_SIZE

显示更多

整数

100

管理接口

类型

默认

重新索引端点的根路径。此值将解析为相对于 ${quarkus.management.root-path} 的路径。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_MANAGEMENT_ROOT_PATH

显示更多

字符串

hibernate-search/standalone/

如果管理界面已开启,则重新索引端点将在管理界面下发布。此属性允许通过将其设置为 `true 来启用此功能。

环境变量:QUARKUS_HIBERNATE_SEARCH_STANDALONE_MANAGEMENT_ENABLED

显示更多

布尔值

false

关于 Duration 格式

要写入持续时间值,请使用标准的 java.time.Duration 格式。有关更多信息,请参阅 Duration#parse() Java API 文档

您还可以使用简化的格式,以数字开头

  • 如果该值仅为一个数字,则表示以秒为单位的时间。

  • 如果该值是一个数字后跟 ms,则表示以毫秒为单位的时间。

在其他情况下,简化格式将被转换为 java.time.Duration 格式以进行解析

  • 如果该值是一个数字后跟 hms,则在其前面加上 PT

  • 如果该值是一个数字后跟 d,则在其前面加上 P

关于 Bean 引用

首先,请注意在配置属性中引用 Bean 是可选的,实际上是不推荐的:您可以通过用 @SearchExtension 注解您的 Bean 来实现相同的结果。有关更多信息,请参阅 本节

如果您确实想使用字符串值在配置属性中引用 Bean,请知道字符串会被解析;以下是最常见的格式

  • bean: 后面跟着一个 @Named CDI Bean 的名称。例如 bean:myBean

  • class: 后面跟着一个类的完全限定名,如果它是 CDI Bean,则通过 CDI 实例化,否则通过其公共的、无参数的构造函数实例化。例如 class:com.mycompany.MyClass

  • 一个任意字符串,引用一个内置实现。可用的值在每个配置属性的文档中都有详细说明,例如 async/read-sync/write-sync/sync 用于 quarkus.hibernate-search-standalone.indexing.plan.synchronization.strategy

也接受其他格式,但仅对高级用例有用。有关更多信息,请参阅 Hibernate Search 的参考文档的 此部分

相关内容