【发布时间】:2019-10-23 15:32:45
【问题描述】:
我有一个 Mongo 集合,其中的文档永远不会更新,而是读取最新的文档,并插入一个新文档,其中一些字段已更新。这些通用文档共享一个标识符document_identifier,将它们与其他文档区分开来。
我想执行一个执行以下操作的查询:
获取所有customer_id 为X 的文档,将它们按document_identifier 分组,然后从每个组中取出最大updated_at 时间戳的文档。它应该完整地返回文档(它们的所有属性)。
示例数据集:
{
document_identifier: "abc",
updated_at: 1000,
customer_id: "123",
...
},
{
document_identifier: "def",
updated_at: 1001,
customer_id: "123",
...
},
{
document_identifier: "abc",
updated_at: 1002,
customer_id: "123",
...
},
{
document_identifier: "def",
updated_at: 10003,
customer_id: "123",
...
},
{
document_identifier: "xyz",
updated_at: 1004,
customer_id: "999",
...
},
{
document_identifier: "abc",
updated_at: 1005,
customer_id: "123",
...
},
{
document_identifier: "def",
updated_at: 1006,
customer_id: "123",
...
},
在上面的示例中,如果我想查询“123”的customer_id,结果将是:
{
document_identifier: "abc",
updated_at: 1005,
customer_id: "123",
...
},
{
document_identifier: "def",
updated_at: 1006,
customer_id: "123",
...
},
我被引导到 Mongo 聚合框架,但似乎无法理解。
非常感谢任何帮助。
编辑:这是我现在拥有的,它似乎正在工作,但我不确定它是否是最佳的:
db.my_colleciton.aggregate([
{
$match: {customer_id: <value to query on>}
},
{
$sort: {updated_at: -1}
},
{
$group: {
_id: "$document_identifier",
my_doc: {$first: "$$ROOT"}
}
},
{
"$replaceRoot": {newRoot: "$my_doc"}
}
])
【问题讨论】:
-
我认为您的结果对于客户 123 文档 ID“def”不准确,我认为这应该显示 updated_at 值 10003 而不是 1006,因为 10003 大于 1006。
-
@barrypicker 我做了一些修改。我遗漏了一些信息,我修正了一个错字。
-
即便如此,您的预期结果还是如我所料。也许我误解了你的意图?
-
小心假设 $group 之前的 $sort 将提供预期的结果。 MongoDB 文档清楚地表明 $group 不会对其输出文档进行排序,因此 $first 现在是可疑的。见docs.mongodb.com/manual/reference/operator/aggregation/group
-
实际上,再次查看文档,Mongo 声明 $first “从每个组的第一个文档中返回一个值。仅当文档处于定义的顺序时才定义顺序。”我认为他们指的是 $group 之前的 $sort。如果是这样,您的查询是安全的。我希望文档更清楚。
标签: mongodb aggregation-framework