2012-02-22 84 views
2

我正在尝试构建自己的搜索引擎进行实验。查询多个单词时搜索索引如何工作?

我知道倒排索引。例如索引单词时。

关键是这个词,并有一个包含该词的文档ID列表。所以,当你搜索这个词,你得到的文件马上

它是如何为多个单词

你得到的每一个字的所有文件和遍历这些文件,看看是否有这两个词的工作?

我觉得情况并非如此。

任何人都知道这个没有投机的真正答案?

+3

如果你可以得到所有一个字一个文件(或文件IDS),你可以做一个字相同B,您也可以在不打开文档本身的情况下生成两个结果集的交集。 – biziclop 2012-02-22 00:47:01

回答

0

您发现文档集的交集为biziclop说,你可以用相当快的方式做到这一点。请参阅this post以及其中链接的文件以获得更正式的描述。

+0

这篇文章并没有真正解决匹配列表_intersection_(即AND查询)的问题,因为它讨论了OR查询。 – jogojapan 2012-02-24 06:04:32

+0

@jogojapan:链接的论文是核心实施细节。我认为最重要的部分是可以通过仅找到最前面的k来改善界限。 – Xodarap 2012-02-24 17:02:04

0

正如指出的biziclop,对于和查询需要交叉匹配列表(又名倒排列表)两个查询词。

在典型的实现方式中,倒排列表被实现为使得它们可以搜索任何给定的文档ID非常有效地(通常,对数时间)。实现这一目标的方法之一是让他们排序(和使用二进制搜索),但注意,这不是小事,因为还需要将它们存储在压缩形式。给定查询A AND B,并且假设对于A有occ(A)匹配并且对于B有occ(B)匹配(即occ(x):=对于项x的匹配列表的长度)。假设在不失一般性的情况下,occ(A)> occ(B),即A在文档中比B更频繁地出现。然后你要做的是遍历B中的所有匹配并在列表中搜索它们中的每一个为A.如果确实列表可以在对数时间内搜索,这意味着你需要

occ(B) * log(occ(A)) 

计算步骤来标识包含两方面的所有比赛。

描述落实各个方面进行一个伟大的书是Managing Gigabytes

0

反向索引是获得交集,用锯齿形alorithm非常有效:

假设你而言是一个列表T

lastDoc <- 0 //the first doc in the collection 
currTerm <- 0 //the first term in T 
while (lastDoc != infinity): 
    if (currTerm > T.last): //if we have passed the last term: 
    insert lastDoc into result 
    currTerm <- 0 
    lastDoc <- lastDoc + 1 
    continue 
    docId <- T[currTerm].getFirstAfter(lastDoc-1) 
    if (docID != lastDoc): 
    lastDoc <- docID 
    currTerm <- 0 
    else: 
    currTerm <- currTerm + 1 

该算法假设有效getFirstAfter(),可以给你的第一符合术语和他的docId的文档大于指定的参数。如果没有的话,它应该返回无穷大。如果条款排列,使得稀有项第一

该算法将是最有效的。

的算法保证在最#docs_matching_first_term * #terms迭代,但实际上 - 它通常会少得多的迭代。

注意:虽然此算法是有效的,但AFAIK lucene不使用它。

更多信息可以在this lecture notes幻灯片11-13在演讲的第一页的复制权限]

-1

我真的不明白为什么人们在谈论路口此找到。

Lucene支持使用布尔查询的查询组合,如果必须的话,您可以无限地嵌套。

QueryParser还支持AND关键字,这将需要这两个单词在文档中。

例(Lucene.NET,C#):

var outerQuery + new BooleanQuery(); 
outerQuery.Add(new TermQuery(new Term("FieldNameToSearch", word1)), BooleanClause.Occur.MUST); 
outerQuery.Add(new TermQuery(new Term("FieldNameToSearch", word2)), BooleanClause.Occur.MUST); 

如果要拆分使用相同的分析仪的话(实际的搜索项),有很多方法可以做到这一点。虽然,QueryParser可能更易于使用。

您可以查看这个答案,例如如何使用您用于索引同一个分析器分割字符串:

No hits when searching for "mvc2" with lucene.net

+0

您的“a”和“b”查询精确计算匹配“a”的文档集和匹配“b”的文档集之间的交集 – fulmicoton 2016-01-08 01:52:49

1

您需要将文档存储到索引文件中的一个字的位置。 您的索引文件结构应该是这样的。 word id - doc id- no。点击的位置。

enter image description here

现在假设查询包含4个字 “W1,W2,W3 W4”。选择包含大部分单词的文件。现在计算它们在文档中的相对距离。大多数单词出现并且其相对距离最小的文档在搜索结果中具有高优先级。

我开发了一个总的搜索引擎,没有使用互联网上的任何爬行或索引工具。你可以阅读更多的信息的详细说明这里 - Search Engine

阅读本文由谷歌founders- click here