Search 查询多个单词时,搜索索引是如何工作的?
我正在尝试建立我自己的搜索引擎进行试验 我知道倒排索引。例如,在索引单词时 关键字是单词,并且具有包含该单词的文档ID列表。所以当你搜索这个词的时候,你会马上得到文档 它如何适用于多个单词 获取每个单词的所有文档,并遍历这些文档以查看是否同时包含这两个单词 我觉得情况并非如此Search 查询多个单词时,搜索索引是如何工作的?,search,lucene,full-text-search,search-engine,Search,Lucene,Full Text Search,Search Engine,我正在尝试建立我自己的搜索引擎进行试验 我知道倒排索引。例如,在索引单词时 关键字是单词,并且具有包含该单词的文档ID列表。所以当你搜索这个词的时候,你会马上得到文档 它如何适用于多个单词 获取每个单词的所有文档,并遍历这些文档以查看是否同时包含这两个单词 我觉得情况并非如此 没有人知道这个问题的真正答案而不去猜测吗?正如biziclop所说,您可以找到文档集的交集,并且可以以相当快的方式完成。有关更正式的描述,请参阅和其中链接的论文。您可以找到biziclop所说的文档集的交集,并且可以以相当
没有人知道这个问题的真正答案而不去猜测吗?正如biziclop所说,您可以找到文档集的交集,并且可以以相当快的方式完成。有关更正式的描述,请参阅和其中链接的论文。您可以找到biziclop所说的文档集的交集,并且可以以相当快的速度完成。有关更正式的描述,请参阅和其中链接的论文。正如biziclop所指出的,对于and查询,您需要将两个查询项的匹配列表(也称为倒排列表)相交 在典型的实现中,反转列表的实现使得可以非常高效地搜索任何给定的文档id(通常,在对数时间内)。实现这一点的一种方法是对它们进行排序(并使用二进制搜索),但请注意,这并不简单,因为还需要以压缩形式存储它们 给定一个查询
a和B
,并假设a有occ(a)匹配项,B有occ(B)匹配项(即occ(x):=术语x的匹配列表长度)。假设occ(A)>occ(B),即A在文档中出现的频率比B高。然后,您要做的是遍历B的所有匹配项,并在A的列表中搜索每个匹配项。如果确实可以在对数时间内搜索列表,这意味着您需要
occ(B) * log(occ(A))
识别包含这两个术语的所有匹配项的计算步骤
一本描述实现各个方面的好书是。正如biziclop所指出的,对于AND查询,您需要将两个查询项的匹配列表(也称为倒排列表)相交 在典型的实现中,反转列表的实现使得可以非常高效地搜索任何给定的文档id(通常,在对数时间内)。实现这一点的一种方法是对它们进行排序(并使用二进制搜索),但请注意,这并不简单,因为还需要以压缩形式存储它们 给定一个查询
a和B
,并假设a有occ(a)匹配项,B有occ(B)匹配项(即occ(x):=术语x的匹配列表长度)。假设occ(A)>occ(B),即A在文档中出现的频率比B高。然后,您要做的是遍历B的所有匹配项,并在A的列表中搜索每个匹配项。如果确实可以在对数时间内搜索列表,这意味着您需要
occ(B) * log(occ(A))
识别包含这两个术语的所有匹配项的计算步骤
描述实现的各个方面的一本好书是。使用之字形算法,反向索引对于获取交叉点非常有效: 假设您的术语是一个列表
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
lastDoc使用之字形算法,倒排索引对于获取交点非常有效:
假设您的术语是一个列表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
lastDoc我真的不明白为什么人们会谈论这个问题
Lucene支持使用BooleanQuery组合查询,如果必须,可以无限期嵌套
QueryParser还支持AND关键字,这将要求两个单词都出现在文档中
例如(Lucene.NET,C#):
如果您想使用同一个分析器拆分单词(您的实际搜索词),也有很多方法可以做到这一点。不过,QueryParser可能更容易使用
您可以查看此答案,例如如何使用用于索引的同一分析器拆分字符串:
我真的不明白为什么人们会谈论这个十字路口
Lucene支持使用BooleanQuery组合查询,如果必须,可以无限期嵌套
QueryParser还支持AND关键字,这将要求两个单词都出现在文档中
例如(Lucene.NET,C#):
如果您想使用同一个分析器拆分单词(您的实际搜索词),也有很多方法可以做到这一点。不过,QueryParser可能更容易使用
您可以查看此答案,例如如何使用用于索引的同一分析器拆分字符串:
您需要将单词在文档中的位置存储在索引文件中。
您的索引文件结构应该如下所示。。
word id-文档id-点击次数-点击位置
现在假设查询包含4个单词“w1 w2 w3 w4”。选择包含大多数单词的文件。现在计算它们在文档中的相对距离。大多数单词出现且相对距离最小的文档在搜索结果中具有较高的优先级
我开发了一个完整的搜索引擎,没有使用互联网上的任何爬行或索引工具。您可以在这里阅读详细说明-
要了解更多信息,请阅读谷歌创始人撰写的这篇文章-您需要将单词在文档中的位置存储在索引文件中。
您的索引文件结构应该如下所示。。
word id-文档id-点击次数-点击位置
现在假设查询包含4个单词“w1 w2 w3 w4”。选择包含大多数单词的文件。现在计算它们在文档中的相对距离。大多数单词出现且相对距离最小的文档在搜索结果中具有较高的优先级
我开发了一个完整的搜索引擎,没有使用互联网上的任何爬行或索引工具。您可以在这里阅读详细说明-
fo