我曾经多次遇到过一些问题,其中除了一个字段在搜索查询中定义了所有字段(一些是针对数据库的,有些是针对数据库的),但是在索引时不知道哪个字段是未知的。我通常的方法是为每个字段创建一个索引并对它们设置操作,或者在SQL的情况下,为每个字段编制索引,然后选择。对于很多领域,这可能会或可能不会比线性搜索更好。
但是,如果我知道一次只会丢失一个字段,那么就时间复杂度或磁盘访问而言,是否可以做得更好?也许是我不熟悉的数据结构?
答案 0 :(得分:1)
从Lucene中获取灵感,您可以从磁盘上的反向索引结构开始,然后在所讨论的所有字段中执行一个跨越迭代器。
E.g。
示例文档
{"id": 1, "network": "NBC", "show": "Wheel of Fortune", "host": "Pat Sajak", "sponsor": "NordicTrack"}
{"id": 2, "network": "NBC", "show": "Jeopardy", "host": "Alex Trebek", "sponsor": "IBM Watson"}
{"id": 3, "network": "NBC", "show": "The Wizard of Odds", "host": "Alex Trebek", "sponsor": "NordicTrack"}
倒置指数
网络:=" NBC" (1,2,3)
show :=" Jeopardy" (2),"赔率精灵" (3),"财富之轮" (1)
主持人:=" Alex Trebek" (2,3)," Pat Sajak" (1)
赞助商:=" IBM Watson" (2)," NordicTrack" (1,3),
发出的查询:
网络: NBC
主持人: Alex Trebek
赞助商: NordicTrack
显示:未知
查询执行
迭代步骤1
网络:=" NBC" (1 ...
将共识ID更新为 1
在所有其他查询字段(如果存在)中进入共识ID
迭代步骤2
网络:=" NBC" (1 ...
主持人:=" Alex Trebek" (2 ...
错误:
id:2
高于共识ID,
将共识ID更新为 2
在所有其他查询字段中进入新的共识ID(如果存在)
迭代步骤3
网络:=" NBC" (
1,2 ......主持人:=" Alex Trebek" (2 ...
赞助商:=" NordicTrack" (
1,3)错误:
id:3
高于共识ID,
将共识ID更新为 3
在所有其他查询字段中进入新的共识ID(如果存在)
迭代步骤4
网络:=" NBC" (
1,2, 3 )主持人:=" Alex Trebek" (
2, 3 )赞助商:=" NordicTrack" (
1, 3 )匹配:所有查询的字段都同意,
- 将 3 添加到匹配列表
...
使用线性迭代,由leapfrog执行的比较次数是查询的所有字段的过帐列表长度的总和。
但是使用Skip Lists可以减少比较次数。 (虽然这需要快速随机访问帖子)。