MongoDB 查找 A 集合中与 B 集合无关的所有文档
MongoDB find all document in A collection which has no relation to B collection
我正在使用 MongoDB 3.4.15,我想从 Rating
集合中找到所有文档,其中 resultid 不在 Result
集合中。
假设每个集合中只有一个文档
评分合集
{
"_id" : ObjectId("6255818aaaaa7f47c79eba01"),
"_class" : "rating",
"ratingid" : "b6885038-17ef-437c-b9c8-be7336a09744",
"value" : 5,
"components" : [
{
"resultid" : "2285e41f-ebe4-4372-8cf8-64dfe91a9733"
},
{
"resultid" : "69053352-d933-46a0-a20c-3863e01b87d6"
}
]
}
结果合集
{
"_id" : ObjectId("62558188aaaa7f47c79eb9ff"),
"_class" : "normal_results",
"resultid" : "2285e41f-ebe4-4372-8cf8-64dfe91a9733",
"totalTime" : Double("10"),
"lastModified" : NumberLong("1649770887268"),
"creationDate" : NumberLong("1649770887268"),
}
在这种情况下,应该返回 Rating
集合的文档,因为 "resultid" : "69053352-d933-46a0-a20c-3863e01b87d6"
不在 Result
集合中。
请帮我写查询。
可以简单的执行$lookup
,比较查找结果的$size
是否等于components
数组的$size
。
在 Mongo v3.4 中,您可以执行以下操作:
db.Rating.aggregate([
{
"$lookup": {
"from": "Result",
"localField": "components.resultid",
"foreignField": "resultid",
"as": "resultLookup"
}
},
{
"$addFields": {
"dedupeComponents": {
"$reduce": {
"input": "$components",
"initialValue": [],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.resultid",
"$$value"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this.resultid"
]
]
}
}
}
}
},
"resultLookup": {
"$reduce": {
"input": "$resultLookup",
"initialValue": [],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.resultid",
"$$value"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this.resultid"
]
]
}
}
}
}
}
}
},
{
$addFields: {
matched: {
$eq: [
{
$size: "$dedupeComponents"
},
{
$size: "$resultLookup"
}
]
}
}
},
{
"$match": {
matched: false
}
},
{
"$project": {
// cosmetics
matched: false,
dedupeComponents: false,
resultLookup: false
}
}
])
这里是Mongo playground供您参考。
我正在使用 MongoDB 3.4.15,我想从 Rating
集合中找到所有文档,其中 resultid 不在 Result
集合中。
假设每个集合中只有一个文档
评分合集
{
"_id" : ObjectId("6255818aaaaa7f47c79eba01"),
"_class" : "rating",
"ratingid" : "b6885038-17ef-437c-b9c8-be7336a09744",
"value" : 5,
"components" : [
{
"resultid" : "2285e41f-ebe4-4372-8cf8-64dfe91a9733"
},
{
"resultid" : "69053352-d933-46a0-a20c-3863e01b87d6"
}
]
}
结果合集
{
"_id" : ObjectId("62558188aaaa7f47c79eb9ff"),
"_class" : "normal_results",
"resultid" : "2285e41f-ebe4-4372-8cf8-64dfe91a9733",
"totalTime" : Double("10"),
"lastModified" : NumberLong("1649770887268"),
"creationDate" : NumberLong("1649770887268"),
}
在这种情况下,应该返回 Rating
集合的文档,因为 "resultid" : "69053352-d933-46a0-a20c-3863e01b87d6"
不在 Result
集合中。
请帮我写查询。
可以简单的执行$lookup
,比较查找结果的$size
是否等于components
数组的$size
。
在 Mongo v3.4 中,您可以执行以下操作:
db.Rating.aggregate([
{
"$lookup": {
"from": "Result",
"localField": "components.resultid",
"foreignField": "resultid",
"as": "resultLookup"
}
},
{
"$addFields": {
"dedupeComponents": {
"$reduce": {
"input": "$components",
"initialValue": [],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.resultid",
"$$value"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this.resultid"
]
]
}
}
}
}
},
"resultLookup": {
"$reduce": {
"input": "$resultLookup",
"initialValue": [],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.resultid",
"$$value"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this.resultid"
]
]
}
}
}
}
}
}
},
{
$addFields: {
matched: {
$eq: [
{
$size: "$dedupeComponents"
},
{
$size: "$resultLookup"
}
]
}
}
},
{
"$match": {
matched: false
}
},
{
"$project": {
// cosmetics
matched: false,
dedupeComponents: false,
resultLookup: false
}
}
])
这里是Mongo playground供您参考。