Lucens做“启动”查询的最佳方式

时间:2013-02-21 15:17:12

标签: lucene startswith

我希望能够执行以下类型的查询:

要索引的数据包括(比方说)音乐视频,其中只有标题很有趣。 我只是想对它们进行索引,然后为它们创建查询,这样,无论用户在查询中使用什么单词或单词,将首先返回包含这些单词的文档,按顺序,在tile的开头,然后返回(在没有特定的顺序)包含至少一个标题任何位置的搜索词的文档。所有这些都应该不区分大小写。

示例:

对于文件:

  • Video1Title = Sea is blue
  • Video2Title = Wild sea
  • Video3Title = Wild sea Whatever
  • Video4Title = Seaside Whatever

如果我搜索“海”,我想得到

  • “Video1Title = Sea is blue”

首先是标题中包含“sea”的所有其他文档,但不是在开头。

如果我搜索“狂野的海洋”我想要

  • Video2Title = Wild sea
  • Video3Title = Wild sea Whatever

首先是所有其他文档中标题为“Wild”或“Sea”的文档,但没有“Wild Sea”作为标题前缀。

如果我搜索“Seasi”,我不想得到任何东西(我不关心关键字标记化和前缀查询)。

现在AFAIKS,没有实际的方法告诉Lucene“找到word1和word2等位于第1和第2和第3位等的文件。”

有模拟该行为的“变通办法”:

  • 将字段索引两次。在field1中,您有单词标记化(可能使用StandardAnalyzer),在field2中,您将它们全部聚集成一个元素(使用KeywordAnalyzer)。然后,如果您搜索类似的内容:

    +(field1:word1 word2 word3)(field2:“word1 word2 word3 *”)

有效地告诉Lucene“文档必须包含标题中的word1或word2或word3,而且那些匹配”title的标题以> word1 word2开始word3<“更好(获得更高的分数)。

  • 在索引它们时,在字段的开头添加“lucene_start_token” Video2Title = Wild sea被编入索引为“title:lucene_start_token Wild sea”,其余为

然后进行查询:

+(title:sea)(标题:“lucene_start_token sea”)

让Lucene返回标题中包含我的搜索词的所有文档,并对匹配“lucene_start_token +搜索词”的人提供更好的分数

我的问题是,是否确实有更好的方法(可能使用PhraseQueryTerm position)?如果没有,上述哪一个更好的性能?

2 个答案:

答案 0 :(得分:5)

您可以使用Lucene Payloads。您可以为字段值的每个项提供自定义提升。

因此,当您为标题编制索引时,您可以开始使用提升因子3(例如):

标题:狂野 | 3.0 生物 | 2.5 蓝色 | 2.0 | 1.5

标题: | 3.0 生物 | 2.5

通过这种方式建立索引,您可以将最近的术语提升到标题的开头。

使用这种方法的主要问题是您必须自己进行标记并“手动”添加所有这些提升信息,因为分析器需要以这种方式构造文本(term1 | 1.1 term2 | 3.0 term3)。

答案 1 :(得分:1)

您可以做的是分别索引标题和每个标记,例如文本wild deep blue endless sea的索引类似于:

title: wild deep blue endless sea
t1: wild
t2: deep
t3: blue
t4: endless
t5: sea

然后,如果有人查询“狂野深入”,则查询将被重写为

title:"wild deep" OR (t1:wild AND t2:deep)

通过这种方式,您始终可以找到所有匹配的文档(如果它们匹配title),但匹配t1..tN令牌会更高的相关文档得分。