我们正在运行一个图书搜索应用程序。它是通过hibernate搜索实现的。
账簿实体定义如下:
@Entity
@Indexed
public class Book{
@DocumentId
private Integer UID;
@Field
private String title;
@Field
private String description;
...}
如果用户搜索图书名称,例如,他们输入Microsoft access 2007,则带有标题或描述的图书包含Microsoft,返回access或2007。这正是我们所期望的。有些书因为关键词2007而完全不相关。我正在寻找一个解决方案,以了解每个关键字的重要性。在这种情况下,2007年在搜索中就不那么重要了。但对于这个搜索,微软、access和2007都没有区别。
第二个用户案例:是否有一个好的分析器可以用于索引和查询,以支持多个短语?我以为hibernate搜索的默认分析器只是将搜索词标记为单个单词?
如果搜索词是microsoft access 2007,则如果包含"microsoft access"、,则结果得分最高
另一个搜索示例:"salt lake city"、"united states",如果结果仅与salt、city或lake匹配,则不期望结果,或者至少,它们应该落后于"salt lake city(盐湖城)"的结果。
有人能给我一些线索吗?
谢谢!
Lucene应该已经对频繁出现的条款进行了折扣,因此在文档之间没有很好的区别。如果你想增加这种效果,你有几个选择:
- 更改默认的相似性函数,并使用新函数对术语进行不同的加权
- 通过首先查找包含给定术语的文档数量,并相应地调整该术语的权重,来增强查询中的低df(高idf)术语
- 编写一个分类器,它可以先验地决定哪些术语不会那么有效(例如,年份数字),并相应地调整它们的权重
- 使用WordNet或维基百科之类的东西作为短语的来源(例如,领导技能),将其作为一个标记进行索引。这将涉及由分析器配置的修改后的TokenStream
我不知道如何区分好的2007和坏的2007。
你可以做的一件事是使用一个分析器,它忽略数字作为描述,而使用常规分析器作为标题。这样一来,只有标题中的数字才会被选中。在实践中,它不是一个完整的分析器,而是一个简单的过滤器,您可以编写并添加到分析器堆栈中。
您还可以对描述进行两次索引,一次忽略数字,另一次不忽略数字。然后,您可以在查询时使用提升因子来搜索这两个字段,但将数字字段的优先级设置为较低。
另一个解决方案是忽略自定义过滤器中的一些数字模式(即年份式数字、个位数数字等):这些将是最常见的噪声数字类型,你会希望忽略它们(我想这是我首先要做的)。
至于短语搜索,只需使用Lucene的PhraseQuery或使用更友好的Hibernate search DSL、
Query luceneQuery = mythQB
.phrase()
.onField("history")
.matching("Thou shalt not kill")
.createQuery();
查询DSL的整个文档在这里