4

我目前正在开发 Lucenes MoreLikeThis 的修改版本,以适应我自己的目的。有一件事我仍然无法理解。创建队列时,MoreLikeThis 会搜索该词条 docFreq 最高的字段。

// go through all the fields and find the largest document frequency
String topField = fieldNames[0];
int docFreq = 0;
for (int i = 0; i < fieldNames.length; i++) {
   int freq = ir.docFreq(new Term(fieldNames[i], word));
   topField = (freq > docFreq) ? fieldNames[i] : topField;
   docFreq = (freq > docFreq) ? freq : docFreq;
}

该字段将在 TermQuery 中使用。这会产生奇怪的结果。

例如,假设您有两个字段,“title”和“body”,并且有两个具有完全相同标题的文档,但它们不会匹配,因为“title”中的所有单词在其他文档中出现的频率更高“身体”,反之亦然。这对我来说似乎很奇怪。

另一个例子:我在一个系统中使用它,该系统通过与用户相关的访问权限过滤结果,并且发生查询的用户无法看到导致所选字段的高 docFreq 的文档。生成的查询没有找到任何文档,尽管用户可以看到很多文档,其中包含确切的术语,只是在错误的字段中。

我想知道为什么他们不只使用所有字段,或者至少使用术语最初出现的字段。当然,这可能是性能问题。但我已经实现它以使用原始文档中出现该术语的所有字段,以及具有最高 docFreq 的字段。我在包含数千个文档的索引上对其进行了测试,但看不出有任何区别(但我没有做任何基准测试)。

那么,谁能告诉我为什么要这样实现?我能想到的唯一原因是在具有很多字段的非常大的索引上表现出色。

//编辑:我实现了第一个例子来澄清问题: http: //pastebin.com/fwdENb3F

4

1 回答 1

2

您应该将MoreLikeThis其视为不适合所有用途的参考实现。如果实现只针对一个字段,那么我们将看到这样的问题:为什么它只搜索标题字段而完全忽略了两个书籍文档具有相同的作者。
您可以使用setFieldNames设置查找相似性的字段。

创建您自己的MoreLikeThis声音版本是最好的方法,尤其是考虑到您需要考虑 ACL。

于 2012-11-25T23:25:42.600 回答