如何根据点击次数在LuceneSearch中订购列表

时间:2009-08-04 08:05:35

标签: c# asp.net lucene lucene.net

我正在使用Lucene Search来获取与搜索文本匹配的文章。是否有任何方法可以按照文章中的点击数量的升序排列它们。

示例:如果我的搜索文本为stack,并且在第一篇文章中出现了两次单词stack,而在第二篇文章中出现了三次stack,第二次出现应该先来,第一个应该是第二个。

我知道如何完成它?

以下是我正在使用的代码

List<LuceneSearchResult> searchResult = new List<LuceneSearchResult>();
LuceneSearchResult result;
IndexReader reader = IndexReader.Open(INDEX_DIR);
Searcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser("Text", analyzer);
//Text and Type are column name

Query q = parser.Parse(string.Format("Text:{0} AND Type:{1}", finalText, type));
Hits hs = searcher.Search(q);
ArrayList idList = new ArrayList();
for (int i = 0; i < hs.Length(); i++)
{

    Document doc = hs.Doc(i);
    result = new LuceneSearchResult();
    result.ID = doc.Get("ID");
    result.Type = doc.Get("Type");


    if (!idList.Contains(result.ID))
    {
        searchResult.Add(result);
        idList.Add(result.ID);
    }

}
return searchResult.ToArray();

5 个答案:

答案 0 :(得分:2)

Lucene按分数对文件进行排名。给定查询的文档的分数有几个组成部分。其中之一是查询字段中的术语频率。但是,对于单个术语的搜索,计算非常简单。它与字段长度中字段规范化中术语出现次数的平方根成正比。这可能是你遇到麻烦的地方。

如果搜索单词“stack”且doc A有1次出现,而doc B有2次出现,如果字段长度明显大于doc B,则doc A仍然可以在结果中排​​名更高。

好消息是你可以禁用字段规范化。坏消息是你需要在索引之前做到这一点,除非你通过Similarity类总是把它排除在外,但我不建议这样做。要在索引时禁用规范,请在索引代码中,在添加到IndexWriter的Field对象上调用Field.setOmitNorms(true)。在您的情况下,这将是“文本”字段。

答案 1 :(得分:1)

Lucene应该自动执行此操作,但这在某种程度上取决于您如何制定查询。默认情况下,如果您使用多个单词执行查询,则这些单词将一起进行OR运算。例如,假设您的查询是这样的(搜索内容字段):

contents:apples oranges

这将返回任何带有术语apples OR oranges的页面。如果一个页面包含单词“apples”50次但没有引用橙色,那么该页面的排名仍然高于仅包含“apples”一次和“oranges”一次的页面。

您可能想做的是和您的查询一样:

contents:apples AND oranges

注意:大写AND

这只会返回同时包含单词“apples”和“oranges”的页面,这可能更接近你想要的内容。

阅读Lucene - Query Parser Syntax,了解有关如何对查询进行论坛的更多信息

答案 2 :(得分:0)

我同意Dan的看法,这应该是Lucene的默认行为。如果您的实施方式不是这样,请添加详细信息,以便我们帮助您诊断原因。 Lucene的Similarity课程文件解释了Lucene得分的细节,这是对命中顺序的负责。

答案 3 :(得分:0)

乍一看,您的代码看起来应该按预期运行 你能告诉我们一个finalText,类型和结果的例子吗? 当我得到意想不到的结果时,我通常会检查实际使用的查询(在调试模式下检查q的值)并在Luke中使用该查询来查看它给出的结果。

在我的代码中,我通常使用hits.Max而不是hits.Length。不知道有什么不同,但这是我注意到的。

另外,作为附注,除非您的程序的其余部分另外指示您,否则您可能想要查看HashTable而不是IdList的ArrayList,它通常更快。

答案 4 :(得分:0)

我已经google了一下,发现Lucene按照点击次数的顺序列出搜索结果,这不是短语出现次数的现象,而是根据各种因素计算的,因此我认为它会不能直接从Lucene那里得到它,但如果你找到某种方式,请告诉我。