我有一个聚合:
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'
}
],我在这里错过了什么?我真的不知道如何处理这个问题。你能推我一下吗?
发布于 2021-05-05 09:08:26
$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" }
}
}
])发布于 2021-05-05 08:08:23
从这个封闭错误报告
使用$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来恢复结构。
https://stackoverflow.com/questions/67396937
复制相似问题