【发布时间】:2013-11-04 21:52:30
【问题描述】:
我有一个带有name 字段的Movie 类。我想与其中包含空格的电影名称进行匹配,以查找没有空格的查询词。
例如:当搜索词为 toystory 时,我希望名称为 Toy Story 的电影出现在结果中。
如何编写我的 Hibernate Search DSL 查询?
【问题讨论】:
标签: java lucene tokenize hibernate-search
我有一个带有name 字段的Movie 类。我想与其中包含空格的电影名称进行匹配,以查找没有空格的查询词。
例如:当搜索词为 toystory 时,我希望名称为 Toy Story 的电影出现在结果中。
如何编写我的 Hibernate Search DSL 查询?
【问题讨论】:
标签: java lucene tokenize hibernate-search
解决此问题的一种方法实际上是索引时间解决方案。您可以使用自定义分析器将电影标题作为连接(无空格)字符串添加到索引中。这样您就可以免费获得所需的功能。
【讨论】:
StandardTokenizerFactory,它根据空格对单词进行标记。对于Toy Story,它将创建令牌toy 和story。理想情况下,我想扩展StandardTokenizerFactory 的功能以创建令牌toy、story 和toy story。我该怎么做?
使用NGramFilterFactory 和LowerCaseFilterFactory 过滤器将分析器添加到Movie 类,然后将此分析器用于名称字段:
@Indexed
@AnalyzerDef(name = "ngram", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class, params = {
@Parameter(name = "minGramSize", value = "3"),
@Parameter(name = "maxGramSize", value = "10")
})
})
public class Movie{
@Field( analyze = Analyze.YES )
@Analyzer( definition="ngram" )
private String name;
// standard setters and getters go here
}
当搜索词为toystory时,名称为Toy Story的电影肯定会出现在结果中,只需使用下一个查询:
QueryBuilder qb = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity( Movie.class ).get();
org.apache.lucene.search.Query query = qb
.keyword()
.onField("name")
.matching("toystory");
.createQuery();
org.hibernate.Query hibQuery =
fullTextSession.createFullTextQuery(query, Movie.class);
List result = hibQuery.list();
【讨论】: