MongoDB:在给定行之前和之后顺序返回行?

时间:2012-03-02 12:27:06

标签: mongodb search find database

在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});

并获得一个游标。在此阶段,不添加任何其他字段,获取上下文的方法是什么?我认为流程是这样的:

  • 对于游标中的每一行:
    • 获取_id字段,存储到x。
    • 执行:collection.find({_ id:{'$ gt':x}})。limit(N)
      • 从每个游标中获取结果。
    • 执行:collection.find({_ id:{'$ lt':x}})。sort({_ id:1})。limit(N)
      • 从每个游标中获取结果。

对于包含R行的结果集,这需要2R + 1次查询。

然而,我想我可以及时换掉空间。是一个可行的替代方法,在后台使用上下文_id更新每一行吗?对于当前包含字段的给定行:

_id, contents, keywords

我会添加一个额外的字段:

_id, contents, keywords, context_ids

然后在随后的搜索中我可以,不知何故,使用这些context_ids,我想?我对MongoDB MapReduce一点也不熟悉,但是它也可以进入画面吗?

我认为最直接的方法是在每行中存储实际上下文行的全文,但这对我来说似乎有些粗糙。明显的优势是单个查询可以返回我需要的上下文。

我感谢所有接受问题范围的答案。我意识到我可以在带外使用Lucene或真正的全文搜索引擎,但我正在尝试感受MongoDB的边缘和功能,所以我会欣赏MongoDB特定的答案。谢谢!

1 个答案:

答案 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)

这也可以简化您的应用程序逻辑,因为您不需要使用相关行重新组合上下文,此查询将返回匹配的行和上下文行。