我的分析器定义如下
@AnalyzerDefs({
@AnalyzerDef(name = "ngram",
tokenizer = @TokenizerDef(factory = KeywordTokenizerFactory.class),
filters = {
//@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class, params = {
@Parameter(name = "minGramSize", value = "3"),
@Parameter(name = "maxGramSize", value = "255") }) }),
//-----------------------------------------------------------------------
@AnalyzerDef(name = "ngram_query",
tokenizer = @TokenizerDef(factory = KeywordTokenizerFactory.class),
filters = {
//@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class)
})
})
@Analyzer(definition = "ngram")
public class EPCAsset extends Asset {
@Field
private String obturatorMaterial;
}
它在索引时间内完美地构成了n克项的向量。但这也会在搜索期间产生n-gram搜索查询。
我想要的是一种搜索查询,它使用n-gram索引进行搜索而又不将搜索词分解成g的方式。
注意:我必须在这里使用n-gram,因为要求是在文本中的任何位置进行搜索。开始或中间。所以我无法选择edge-n-gram。
示例: 输入要作为索引 ICQ 234
的数据然后在索引时间内其项向量为
"234" " 23" " 234" "cq " "cq 2" "cq 23" "cq 234" "icq" "icq " "icq 2" "icq 23" "icq 234" "q 2" "q 23" "q 234"
现在,当我搜索 icq 时,它可以完美运行。但它也适用于 icqabc ,因为在搜索期间它会进行n克的搜索查询。因此,有一种方法可以在搜索期间不破坏搜索词,而是使用n-gram索引进行搜索。
这是我的搜索查询建筑物
FullTextEntityManager fullTextEntityManager = Search
.getFullTextEntityManager(entityManager);
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(entityClass).get();
Query query = qb.phrase().onField("obturatorMaterial").sentence("icqabc").createQuery();
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query,
entityClass);
fullTextQuery.getResultList()
我正在使用弹性搜索作为Hibernate搜索的后端。
编辑: 我还按照@yrodiere的答案应用了查询时间分析器,但它给了我错误。
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(entityClass).overridesForField("obturatorMaterial","ngram_query").get();
org.hibernate.search.exception.SearchException:HSEARCH000353:未知分析器:“ ngram_query”。确保已定义此分析器。
编辑
根据此链接overriderForField when using elasticsearch backed hibernate search
我现在可以定义一个查询时间2nd分析器,它解决了这个问题。
答案 0 :(得分:1)
您要么需要使用search time analyzer,要么很可能是搜索期间的关键字分析器。或需要使用term
查询而不是match
查询,这意味着对其进行分析意味着它使用的分析器使用的索引时间相同。
详细了解term query和match query,以了解更多信息。
编辑:-https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html明确讨论了在 edgeNGram令牌生成器和自动完成功能的情况下 search_analyzer 的使用搜索,这正是您的用例。
答案 1 :(得分:1)
首先,您应该仔细检查一个ngram过滤器是否确实是您想要的。我之所以这样说是因为ngram分析器通常同时用于索引和查询,因此它提供了模糊匹配。这就是分析仪的重点。
当用户键入cq 2
时,您真的需要匹配吗?是否有意义?在实现自动完成功能时,人们通常更喜欢只将包含开始的单词与用户输入进行匹配,因此i
会匹配,ic
和icq
也会匹配,但cq 2
除外。如果这正是您想要的,则应查看“ edge_ngram”过滤器。它可以改善匹配的相关性,也不需要太多的磁盘空间。
现在,即使使用“ edge_ngram”过滤器,您也需要在查询时禁用ngram。在Hibernate Search中,这是通过“覆盖”分析器来完成的。
然后,使用它来创建查询构建器:
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(EPCAsset.class)
.overridesForField( "obturatorMaterial", "ngram_query" )
.get();
请注意,如果您依靠Hibernate Search将索引架构和分析器推送到Elasticsearch,则必须使用hack才能推送仅查询分析器:默认情况下,仅实际使用的分析器在索引期间被推送。参见https://discourse.hibernate.org/t/cannot-find-the-overridden-analyzer-when-using-overridesforfield/1043/4