【问题标题】:Efficiently query missing integers in a range on a field?有效地查询字段范围内缺失的整数?
【发布时间】:2016-06-12 22:44:19
【问题描述】:

我有一个用于备份服务的数据库,我正在写 to backup Yahoo! Groups。它逐步检索具有连续数字 id 的消息。存储在'message_id' 字段中。因此,如果服务上的最后一条消息是消息号 10000,那么一旦备份完成,数据库应该包含 10000 个文档,每个文档的排序 'message_id's 等于 range(1, 10000+1)

我想编写一个查询来生成缺少的消息 ID。因此,如果我在数据库中有 9995 个文档,并且缺少消息 10、15、49、99 和 1043,它应该返回 [10, 15, 49, 99, 1043]

我已完成以下操作,仅从数据库中获取 id 并在我的应用代码中运行一个集合交集:

def missing_message_ids(self):
    """Return the set of the ids of all missing messages.."""
    latest = self.get_latest_message()
    ids = set(range(1, latest['_id']+1))
    present_ids = set(doc['_id'] for doc in self.db.messages.find({}, {'_id': 1}))
    return ids - present_ids

这对我的目的来说很好,但对于大量消息来说似乎它可能会变得太慢。这更多是出于好奇,而不是真正的性能要求:有没有更有效的方法可以做到这一点,也许完全在数据库引擎上?

【问题讨论】:

    标签: python mongodb performance database


    【解决方案1】:

    在 SQL 单词中,我们可以使用 CTE,在 mongo 中,我们可以使用 $lookup 的聚合作为一种 CTE(通用表表达式)

    拥有这种数据结构

    {
        "_id" : ObjectId("575deea531dcfb59af388e17"),
        "mesId" : 4.0
    }, {
        "_id" : ObjectId("575deea531dcfb59af388e18"),
        "mesId" : 6.0
    }
    

    如果缺少"mesId" : 5.0,我们可以使用这个聚合查询,它将投影所有下一个预期的ID,并加入它们。这里的限制是如果我们在序列中丢失了多个消息,但这可以通过投影下一个 Id 并再次进行 $lookup 来扩展。

    var project = {
        $project : {
            _id : 0,
            mesId : 1,
            nextId : {
                $sum : ["$mesId", 1]
            }
        }
    }
    var lookup = {
        $lookup : {
            from : "claudiu",
            localField : "nextId",
            foreignField : "mesId",
            as : "missing"
        }
    }
    var match = {
        $match : {
            missing : []
        }
    }
    
    db.claudiu.aggregate([project, lookup, match])
    

    和输出:

    {
        "mesId" : 4.0,
        "nextId" : 5.0,
        "missing" : []
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-28
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 2013-07-18
      • 2023-03-16
      相关资源
      最近更新 更多