我试图得到任意数量的外键的“前”2项,按某些键排序。我有以下几点,这似乎是可行的:
db.getCollection('col1').aggregate([
{$match: {fk: {$in: [1, 2]}}}
{$sort: {name: -1}},
{$group: {_id: "$fk", items: {$push: "$ROOT"} }},
{$project: {items: {$slice: ["$items", 2]} }}
])我的问题是: MongoDB是否保证,当我在聚合的最后一步深入到$sort中的$project中的$slice时,将保持在通过D1进行聚合的第二步中应用的排序?
我看到的数据表明,MongoDB目前的行为是这样的,但我想知道这是否是规范,或者MongoDB是否可以以不同的顺序返回items数组,如果优化器决定这样做是有利的。
发布于 2021-03-26 14:27:52
虽然被接受的答案是正确的,因为$group阶段不会保留顺序,但我认为它遗漏了一些重要的信息,可能会产生误导。
如果您查看Jira机票链接上的注释,它会将其清除到上面。基本上,它说$group在“组”内维持顺序,但是在组阶段之后的阶段中,顺序不会得到保证。
因此,$items将在示例中按name: -1排序,在$project阶段调用$slice 2将导致按名称排序的前2 items。
因此,我想,例如,如果您有以下数据
[
{ fk: 1, name: 'James' },
{ fk: 2, name: 'Zelda' },
{ fk: 2, name: 'Victor' },
{ fk: 1, name: 'Becky' },
{ fk: 1, name: 'Carlos' },
{ fk: 2, name: 'Katie' },
]运行示例查询
db.col1.aggregate([
{ $match: { fk: { $in: [1, 2] } } },
{ $sort: { name: -1 } },
{ $group: { _id: "$fk", items: { $push: "$ROOT" } } },
{ $project: { items: {$slice: ["$items", 2] } } }
])你会得到
{ _id: 2, items: [ { fk: 2, name: "Zelda" }, { fk: 2, name: "Victor" }] }
{ _id: 1, items: [ { fk: 1, name: "James" }, { fk: 1, name: "Carlos" }] },它按降序返回前两个名称。
但是如果您将排序改为在fk上
db.col1.aggregate([
{ $match: { fk: { $in: [1, 2] } } },
{ $sort: { fk: -1 } },
{ $group: { _id: "$fk", items: { $push: "$ROOT" } } },
{ $project: { items: {$slice: ["$items", 2] } } }
])你可以看到
{ _id: 1, items: [ { fk: 1, name: "James" }, { fk: 1, name: "Becky" } ] }
{ _id: 2, items: [ { fk: 2, name: "Zelda" }, { fk: 2, name: "Victor" } ] }您可以看到,_id (即fk)没有按降序排序。如果希望通过_id对其进行排序,则只需在$group阶段之后添加排序即可
https://dba.stackexchange.com/questions/197434
复制相似问题