我有一个用于备份服务的数据库,我正在编写 to backup Yahoo! Groups .它以增量方式检索具有连续数字 ID 的消息。存储在 'message_id'
字段中。因此,如果服务上的最后一条消息是消息编号 10000,则备份完成后,数据库应包含 10000 个文档,每个文档的排序 'message_id'
等同于 范围(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
这对我来说很好,但对于大量消息来说似乎太慢了。这更多是出于好奇而不是真正的性能要求:是否有更有效的方法来做到这一点,也许完全在数据库引擎上?
最佳答案
在 SQL word 中,可以使用 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" : []
}
关于python - 高效查询字段范围内缺失的整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37779798/