在MongoDB中,给定一个返回一组行的游标的find()操作符,返回“上下文”行的惯用和时间效率是什么,即每行之前和/或之后顺序排列的行在集合?
对我来说,解释这个概念的最简单方法是使用支持上下文搜索的ack。给定一个文件:
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
这是ack的输出:
C:\temp>ack.pl -C 2 "line 4" test.txt
line 2
line 3
line 4
line 5
line 6
我将日志数据存储在MongoDB集合中,每行一个文档。每个日志都被标记为关键字,并且这些关键字被编入索引,这为我提供了便宜的全文搜索。
我执行了沼泽标准:
collection.find({keywords: {'$all': ['key1', 'key2']}}, {}).sort({datetime: -1});
并获得一个游标。在此阶段,不添加任何其他字段,获取上下文的方法是什么?我认为流程是这样的:
对于包含R行的结果集,这需要2R + 1次查询。
然而,我想我可以及时换掉空间。是一个可行的替代方法,在后台使用上下文_id更新每一行吗?对于当前包含字段的给定行:
_id, contents, keywords
我会添加一个额外的字段:
_id, contents, keywords, context_ids
然后在随后的搜索中我可以,不知何故,使用这些context_ids,我想?我对MongoDB MapReduce一点也不熟悉,但是它也可以进入画面吗?
我认为最直接的方法是在每行中存储实际上下文行的全文,但这对我来说似乎有些粗糙。明显的优势是单个查询可以返回我需要的上下文。
我感谢所有接受问题范围的答案。我意识到我可以在带外使用Lucene或真正的全文搜索引擎,但我正在尝试感受MongoDB的边缘和功能,所以我会欣赏MongoDB特定的答案。谢谢!
答案 0 :(得分:3)
我认为您存储context_ids
或类似内容的方法可能是最佳选择。如果你能够存储你需要的所有上下文行的context_ids
(这假设它是一个固定大小的上下文量 - 比如前后5行),那么你可以查询所有的使用$in
:
# pseudocode
for each matching row:
context_rows = db.logs.find({_id: {$in: row['context_ids']}}).sort({_id: 1})
row_with_context = [context_rows_before_row] + row + [context_rows_after_row]
我认为知道上下文行集 - 特别是行之后的行可能很困难,因为任何给定行之后的行不一定存在。
一种替代方案,它可以避免这个问题(但仍然需要一个固定的,已知的提前时间量的上下文)只是在相关行之前存储第一行上下文的_id(即插入时) ,你可以缓冲前N行,其中N是上下文的数量) - 调用此first_context_id
- 然后查询如下:
# pseudocode
for each matching row:
rows_with_context = db.logs.find({_id: {$gte: row['first_context_id']}}).sort({_id: 1}).limit(N * 2 + 1)
这也可以简化您的应用程序逻辑,因为您不需要使用相关行重新组合上下文,此查询将返回匹配的行和上下文行。