我想使用两个数组的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
的{{1}}或$unwind
之类的各种内容,但我无法得到结果。
答案 0 :(得分:1)
理想情况下,您需要$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"
}
}
}
}}
])
对于匹配的&#34;索引&#34;它基本上通过$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
。< / p>
在任何一种情况下,都不需要自我加入&#34;使用$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"
}
]
}
一般来说,根本没有任何聚合运算符的原因,因为这种操作通常最好留在游标中进行后处理。事实上,因为你实际上是#34;添加&#34;要返回文档的数据,在通过网络发送文档后进行修改会更好。
作为上面显示为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)] }
)
)
}
)
)
产生完全相同的结果,并且通常更容易阅读和解释