我正在尝试根据他们的_id不存在于ObjectId的数组中来匹配文档。
Mongodb版本:3.2
这是我的疑问:
db.subscriptions.aggregate(
[
{ $match : { "device": { $exists: true } } },
{
$lookup : {
from: "devices",
localField: "device",
foreignField: "_id",
as: "device"
}
},
{ $match : { "device.0" : { $exists: true } } },
{ $unwind: "$device" },
{ $project : {"_id": 1, "subs": "$device.subscriptions" } },
{ $match: { "_id": { $in: this.subs } } }
]
)
我有两个收集订阅和设备。 文档订阅具有属性设备,该属性设备是引用设备的ObjectId。设备文档有一个objectId数组,引用订阅。这是一对多的关系。
第1步: 匹配订阅谁具有设备属性(它不是一个干净的清洁数据库)
第2步: 我正在执行查找以在订阅中获取我的设备文档
第3步: 再次匹配查找确实给出结果的事实
第4步: 展开设备导致查找事物给我一个数组(我不太明白为什么')
第5步: 预订订阅数组和订阅ID以使用更简单的文档:
{
"_id" : ObjectId("587e265cb9b235243c7f9960"),
"subs" : [
ObjectId("5899a894b1e11521a44a96f7"),
ObjectId("5a8c494db0bed60b389cb1da")
]
}
第6步: 这就是出现错误的地方,mongo给我发了一个.subs不是一个数组,所以我不能使用$ nin => “errmsg”:“$ in需要一个数组”
我尝试了多种格式:“this.subs”,“$ subs”,这些都不起作用。
有人可以帮助我吗?
西奥
答案 0 :(得分:1)
在3.2中尝试以下聚合。您无法比较$match
阶段中的文档字段。因此,您必须创建一个中间字段(cmp)来保存来自此类比较的结果和$ match阶段以比较结果。也没有$ in(聚合运算符)。你必须使用$setIsSubset
来模仿这种比较。
db.subscriptions.aggregate(
[
previous stages stages until $unwind
{$project:{
add all the fields you want in response,
"cmp":{$not:{$setIsSubset: [["$_id"], "$device.subscriptions"]}}
}},
{$match: {"cmp": true}}
]
)
升级到3.4,您可以使用$in(aggregation)
运营商及以下渠道。
db.subscriptions.aggregate(
[
previous stages stages until $unwind
{$project:{
add all the fields you want in response,
"cmp":{$not:{$in: ["$_id", "$device.subscriptions"]}}
}},
{$match: {"cmp": true}}
]
)
升级到3.6,您可以使用$match
$in(aggregation)
内的$expr
运算符,{{3}}允许您使用聚合运算符。
db.subscriptions.aggregate(
[
previous stages stages until $unwind
{$match: {"$expr": {$not:{$in: ["$_id", "$device.subscriptions"]}}}}
]
)