【问题标题】:MongoDB: returning rows sequentially before and after a given row?MongoDB:在给定行之前和之后按顺序返回行?
【发布时间】:2012-03-20 22:54:45
【问题描述】:

在 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 特定的答案。谢谢!

【问题讨论】:

    标签: mongodb search find database


    【解决方案1】:

    我认为您存储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)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2017-12-15
      • 1970-01-01
      相关资源
      最近更新 更多