我想使用两个数组的 ID 将数据合并到一个集合中。
一个例子如下所示。
{
"_id": ObjectId ("5976fd2eb0adec0a32fa9831"),
"People": [
{
"_id": 1, <--- ID
"Name": "jane"
},
{
"_id": 2, <--- ID
"Name": "Mark"
}
],
"Contents": [
{
"userID": 2, <--- People ID
"Text": "111"
},
{
"userID": 1, <--- People ID
"Text": "Hi"
}
]
}
我想制作上述文件如下。
{
"_id": ObjectId ("5976fd2eb0adec0a32fa9831"),
"People": [
{
"_id": 1,
"Name" : "Jane"
},
{
"_id": 2,
"Name": "Mark"
}
],
"Contents": [
{
"userID": 2,
"Name": "Mark", <-- Adding
"Text": "111",
},
{
"userID": 1,
"Name": "Jane", <-- Adding
"Text": "Hi",
}
]
}
我尝试了各种类似$lookup
或$unwind
的事情,.aggregate()
但我无法得到结果。
您想要$map
并且$indexOfArray
理想情况下:
db.collection.aggregate([
{ "$addFields": {
"Contents": {
"$map": {
"input": "$Contents",
"as": "c",
"in": {
"userID": "$$c.userID",
"Name": {
"$arrayElemAt": [
"$People.Name",
{ "$indexOfArray": [ "$People._id", "$$c.userID" ] }
]
},
"Text": "$$c.Text"
}
}
}
}}
])
它基本上从另一个数组中$arrayElemAt
获取值,用于匹配由$indexOfArray
.
如果您的 MongoDB 需要回退没有该运算符的版本,那么您可以$filter
改用:
db.collection.aggregate([
{ "$addFields": {
"Contents": {
"$map": {
"input": "$Contents",
"as": "c",
"in": {
"userID": "$$c.userID",
"Name": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": "$People",
"as": "p",
"cond": { "$eq": [ "$$p._id", "$$c.userID" ] }
}
},
"as": "p",
"in": "$$p.Name"
}},
0
]
},
"Text": "$$c.Text"
}
}
}
}}
])
基本上你可以$filter
比较另一个数组的结果,并简单地通过索引返回第一个匹配元素。0
$arrayElemAt
在任何一种情况下,都不需要使用“自连接” $lookup
,这只是最好避免的真正不必要的开销。
从问题中的文档中,您会得到以下信息:
/* 1 */
{
"_id" : ObjectId("5976fd2eb0adec0a32fa9831"),
"People" : [
{
"_id" : 1.0,
"Name" : "jane"
},
{
"_id" : 2.0,
"Name" : "Mark"
}
],
"Contents" : [
{
"userID" : 2.0,
"Name" : "Mark",
"Text" : "111"
},
{
"userID" : 1.0,
"Name" : "jane",
"Text" : "Hi"
}
]
}
不过,一般来说,根本没有任何聚合运算符的理由,因为这种操作通常最好留给游标中的后处理。实际上,由于您实际上是将数据“添加”到要返回的文档中,因此最好在通过网络发送文档后进行修改。
作为上面显示为 shell 的 JavaScript 的常见习语:
db.collection.find().map( d =>
Object.assign(
d,
{
"Contents": d.Contents.map( c =>
Object.assign(c,
{ "Name": d.People.map(p => p.Name)[d.People.map(p => p._id).indexOf(c.userID)] }
)
)
}
)
)
产生完全相同的结果,并且通常更容易在眼睛上阅读和解释
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句