我有这个聚合:
db.getCollection("users").aggregate([
{
"$match": {
"_id": "5a708a38e6a4078bd49f01d5"
}
},
{
"$lookup": {
"from": "user-locations",
"localField": "locations",
"as": "locations",
"foreignField": "_id"
}
}
])
它运行良好,但有一件小事情我不明白并且无法修复。 在查询输出中,
locations
数组由ObjectId
重新排序,我确实需要保持数据的原始顺序。这是
locations
集合中的
users
数组的样子
'locations' : [
ObjectId("5b55e9820b720a1a7cd19633"),
ObjectId("5a708a38e6a4078bd49ef13f")
],
这是聚合后的结果:
'locations' : [
{
'_id' : ObjectId("5a708a38e6a4078bd49ef13f"),
'name': 'Location 2'
},
{
'_id' : ObjectId("5b55e9820b720a1a7cd19633"),
'name': 'Location 1'
}
],
我在这里缺少什么?我真的不知道如何处理这个问题。
可以推我一下吗?
$lookup
不保证结果文档的顺序,您可以尝试一种管理文档自然顺序的方法,
$unwind
解构
locations
数组并添加自动
index
数字将从0开始,
$lookup
与地点
$set
从
locations
选择第一个元素
$sort
按
index
字段升序排列
$group
通过
_id
并重建
locations
数组
db.users.aggregate([
{ $match: { _id: "5a708a38e6a4078bd49f01d5" } },
{
$unwind: {
path: "$locations",
includeArrayIndex: "index"
}
},
{
$lookup: {
from: "user-locations",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{ $set: { locations: { $arrayElemAt: ["$locations", 0] } } },
{ $sort: { index: 1 } },
{
$group: {
_id: "$_id",
locations: { $push: "$locations" }
}
}
])
已关闭的错误报告:
使用$lookup时,不保证返回文档的顺序。文档按“自然顺序”返回 - 正如它们在数据库中遇到的那样。获得保证一致顺序的唯一方法是向查询添加 $sort 阶段。基本上任何 Mongo 查询/管道的工作方式都是按照匹配的顺序返回文档,这意味着不能保证“正确”的顺序,尤其是在涉及 indes 用法的情况下。
你应该做的是按照建议添加一个
$sort
阶段,如下所示:
db.collection.aggregate([
{
"$match": {
"_id": "5a708a38e6a4078bd49f01d5"
}
},
{
"$lookup": {
"from": "user-locations",
"let": {
"locations": "$locations"
},
"pipeline": [
{
"$match": {
"$expr": {
"$setIsSubset": [
[
"$_id"
],
"$$locations"
]
}
}
},
{
$sort: {
_id: 1 // any other sort field you want.
}
}
],
"as": "locations",
}
}
])
您还可以保留您正在使用的原始 $lookup
语法,只需
$unwind
、
$sort
,然后
$group
即可恢复结构。
db.getCollection("users").aggregate([
{
"$match": {
"_id": "5a708a38e6a4078bd49f01d5"
}
},
{
"$lookup": {
"from": "user-locations",
"localField": "locations",
"foreignField": "_id",
"let": {
indexArray: "$locations",
},
"pipeline": [
{
"$addFields": {
"index": { "$indexOfArray": ["$$indexArray", "$_id"] }
}
},
{
"$sort": { "index": 1 }
}
],
"as": "locations",
}
}
])