执行条件查找,如果集合中没有数据,则添加自定义数据
Perform a conditional lookup, and add custom data if from collection has no data
我有两个合集
collection1 : [
{
_id:"90b992b7-b85f-4e1c-9080-fc3e2dba0db0",
pIds: [ "47c9124d-f027-4221-8d60-9f491993d923", "08c89e83-ad62-443c-a731-3c6ccd9ca3af" ]
}
]
和
collection2 : [
{
_id: "47d44016-ff84-44dc-b650-abab36d5f661",
userId: "47c9124d-f027-4221-8d60-9f491993d923",
isOnline: true
}
]
collection2 有 "47c9124d-f027-4221-8d60-9f491993d923"
这个 userId 的数据,但是 collection2 没有 "08c89e83-ad62-443c-a731-3c6ccd9ca3af"
这个 userId 的数据。
现在想要像下面这样的输出
output : [
{
_id:"90b992b7-b85f-4e1c-9080-fc3e2dba0db0",
pIds: [
{
userId: "47c9124d-f027-4221-8d60-9f491993d923",
isOnline: true
},
{
userId: "08c89e83-ad62-443c-a731-3c6ccd9ca3af",
isOnline: false
},
]
}
]
尝试过
$lookup: {
from: "collection2",
let: { pIds: "$pIds" },
pipeline: [
{ $match: { $expr: { $in: ["$userId", "$$pIds"] } } },
{ $project: { _id: 0 } },
],
as: "pId",
}
任何解决方案都会有很大帮助....
提前致谢
db.collection1.aggregate([
{
"$unwind": "$pIds"
},
{
"$lookup": {
"from": "collection2",
"localField": "pIds",
"foreignField": "userId",
"as": "docs"
}
},
{
"$group": {
"_id": "$_id",
"pids": {
"$push": {
userId: "$pIds",
isOnline: { "$ifNull": [ { $first: "$docs.isOnline" }, false ] }
}
}
}
}
])
这是另一种方法。我想知道接受的答案是否有任何改进。我想这归结为 "$unwind"
、"$group"
与 "$map"
、"$mergeObjects"
、"$reduce"
、"$filter"
的性能对比。我不确定如何衡量。
db.collection1.aggregate([
{
"$lookup": {
"from": "collection2",
"localField": "pIds",
"foreignField": "userId",
"as": "docs"
}
},
{
"$project": {
"_id": 1,
"pIds": {
"$map": {
"input": "$pIds",
"as": "pId",
"in": {
"$mergeObjects": [
{ "userId": "$$pId" },
{ "isOnline": {
"$reduce": {
"input": "$docs",
"initialValue": false,
"in": {
"$or": [
false,
{
"$getField": {
"field": "isOnline",
"input": {
"$first": {
"$filter": {
"input": "$docs",
"as": "doc",
"cond": { "$eq": [ "$$pId", "$$doc.userId" ] }
}
}
}
}
}
]
}
}
}
}
]
}
}
}
}
}
])
在 mongoplayground.net 上试用。
我有两个合集
collection1 : [
{
_id:"90b992b7-b85f-4e1c-9080-fc3e2dba0db0",
pIds: [ "47c9124d-f027-4221-8d60-9f491993d923", "08c89e83-ad62-443c-a731-3c6ccd9ca3af" ]
}
]
和
collection2 : [
{
_id: "47d44016-ff84-44dc-b650-abab36d5f661",
userId: "47c9124d-f027-4221-8d60-9f491993d923",
isOnline: true
}
]
collection2 有 "47c9124d-f027-4221-8d60-9f491993d923"
这个 userId 的数据,但是 collection2 没有 "08c89e83-ad62-443c-a731-3c6ccd9ca3af"
这个 userId 的数据。
现在想要像下面这样的输出
output : [
{
_id:"90b992b7-b85f-4e1c-9080-fc3e2dba0db0",
pIds: [
{
userId: "47c9124d-f027-4221-8d60-9f491993d923",
isOnline: true
},
{
userId: "08c89e83-ad62-443c-a731-3c6ccd9ca3af",
isOnline: false
},
]
}
]
尝试过
$lookup: {
from: "collection2",
let: { pIds: "$pIds" },
pipeline: [
{ $match: { $expr: { $in: ["$userId", "$$pIds"] } } },
{ $project: { _id: 0 } },
],
as: "pId",
}
任何解决方案都会有很大帮助....
提前致谢
db.collection1.aggregate([
{
"$unwind": "$pIds"
},
{
"$lookup": {
"from": "collection2",
"localField": "pIds",
"foreignField": "userId",
"as": "docs"
}
},
{
"$group": {
"_id": "$_id",
"pids": {
"$push": {
userId: "$pIds",
isOnline: { "$ifNull": [ { $first: "$docs.isOnline" }, false ] }
}
}
}
}
])
这是另一种方法。我想知道接受的答案是否有任何改进。我想这归结为 "$unwind"
、"$group"
与 "$map"
、"$mergeObjects"
、"$reduce"
、"$filter"
的性能对比。我不确定如何衡量。
db.collection1.aggregate([
{
"$lookup": {
"from": "collection2",
"localField": "pIds",
"foreignField": "userId",
"as": "docs"
}
},
{
"$project": {
"_id": 1,
"pIds": {
"$map": {
"input": "$pIds",
"as": "pId",
"in": {
"$mergeObjects": [
{ "userId": "$$pId" },
{ "isOnline": {
"$reduce": {
"input": "$docs",
"initialValue": false,
"in": {
"$or": [
false,
{
"$getField": {
"field": "isOnline",
"input": {
"$first": {
"$filter": {
"input": "$docs",
"as": "doc",
"cond": { "$eq": [ "$$pId", "$$doc.userId" ] }
}
}
}
}
}
]
}
}
}
}
]
}
}
}
}
}
])
在 mongoplayground.net 上试用。