elasticsearch - Hibernate Search:Elasticsearch 和 Lucene 产生不同的搜索结果
问题描述
我正在尝试使用 Spring Data Rest 和 Hibernate Search 为我的 REST 后端实现一个非常基本的搜索功能。我想允许用户通过将查询字符串传递给搜索函数来执行任意查询。为了能够更轻松地在本地运行后端并避免启动 Elasticsearch 来运行测试,我希望能够在这些情况下使用本地索引。
我的问题是,与 Elasticsearch 相比,使用本地索引的以下代码不会产生相同的结果。我试图将以下代码限制在我认为相关的范围内。
实体:
@Indexed(index = "MyEntity")
@AnalyzerDef(name = "ngram",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class,
params = {
@Parameter(name = "minGramSize", value = "2"),
@Parameter(name = "maxGramSize", value = "3") } )
}
)
public class MyEntity {
@NotNull
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES, analyzer = @Analyzer(definition = "ngram"))
private String name;
@Field(analyze = Analyze.YES, store = Store.YES)
@FieldBridge(impl = StringCollectionFieldBridge.class)
@ElementCollection(fetch = FetchType.EAGER)
private Set<String> tags = new HashSet<>();
}
本地索引的 application.yml:
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: false
用于 Elasticsearch 的 application.yml:
spring:
jpa:
hibernate:
ddl-auto: create-drop
properties:
hibernate:
search:
default:
indexmanager: elasticsearch
elasticsearch:
host: 127.0.0.1:9200
required_index_status: yellow
搜索端点:
private static String[] FIELDS = { "name", "tags" };
@Override
public List<MyEntity> querySearch(String queryString) throws ParseException {
QueryParser queryParser = new MultiFieldQueryParser(FIELDS, new SimpleAnalyzer());
queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
org.apache.lucene.search.Query query = queryParser.parse(queryString);
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(this.entityManager);
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, MyEntity.class);
return persistenceQuery.getResultList();
}
我创建了一个具有以下值的 MyEntity 实例:
$ curl 'localhost:8086/myentities'
{
"_embedded" : {
"myentities" : [ {
"name" : "Test Entity",
"tags" : [ "bar", "foobar", "foo" ],
"_links" : {
...
}
} ]
},
"_links" : {
...
}
}
以下查询使用 Elasticsearch 工作(返回该实体):
- 名称:测试
- 名称:实体
- 标签:酒吧
使用本地索引,我得到了“tags:bar:”的结果,但是对 name 字段的查询没有返回结果。任何想法为什么会这样?
解决方案
您应该确保 Hibernate Search 正确创建了 Elasticsearch 映射。默认情况下,Hiberante Search 只会在缺少映射时创建映射。
如果您启动了一次应用程序,然后更改了映射,然后再次启动了应用程序,则该name
字段可能在 Elasticsearch 中不正确。
在开发模式下,试试这个:
spring:
jpa:
hibernate:
ddl-auto: create-drop
properties:
hibernate:
search:
default:
indexmanager: elasticsearch
elasticsearch:
host: 127.0.0.1:9200
required_index_status: yellow
index_schema_management_strategy: drop-and-create-and-drop
请注意,不幸的是,成功索引文档并不表示您的映射是正确的:当您尝试索引未知字段并试图猜测其类型时,Elasticsearch 甚至会动态创建字段(通常是错误的,在文本字段的情况下......)。您可以使用validate
索引管理策略来确保在引导时,Elasticsearch 映射与 Hibernate Search 同步。
推荐阅读
- python - 使用python删除许多子文件夹中的目标文件夹
- azure-devops - Azure 工作者 - 完成发布管道
- windows - 无法使用 Ansible 执行 win_ping
- python - Docker:Alpine:Django - 安装 python mysqlclient 库时出错
- gitlab - LDAP 到 gitlab 用户同步 oauth 令牌
- powerbi - 按日期过滤的表格中缺少行
- python - 歌词天才的歌词有时以“EmbedShare URLCopyEmbedCopy”结尾
- c++ - 使用 C++ / GCC / Linux 有时无法捕获异常
- c# - VS2019 登录到 azure 抛出:“对象引用未设置为对象的实例。”
- android - 如何在 android 11 的 /Android/media 中创建文件夹?