Javascript Mongodb从输入数组中查找数组字段中的子集
假设我有下面的dbJavascript Mongodb从输入数组中查找数组字段中的子集,javascript,mongodb,mongoose,nosql,Javascript,Mongodb,Mongoose,Nosql,假设我有下面的db const data = [ { "chapter": 1, "targets": [ { type: 'user', recipientId: 1 } ], "challenge": [ { "activate": true, "challengeId
const data = [
{
"chapter": 1,
"targets": [
{
type: 'user',
recipientId: 1
}
],
"challenge": [
{
"activate": true,
"challengeId": "ch-1"
},
{
"activate": true,
"challengeId": "ch-2"
},
{
"activate": true,
"challengeId": "ch-3"
},
]
},
{
"chapter": 1,
"targets": [
{
type: 'user',
recipientId: 2
}
],
"challenge": [
{
"activate": true,
"challengeId": "ch-2"
},
{
"activate": true,
"challengeId": "ch-3"
},
{
"activate": true,
"challengeId": "ch-4"
},
]
},
{
"chapter": 1,
"targets": [
{
type: 'user',
recipientId: 3
}
],
"challenge": [
{
"activate": true,
"challengeId": "ch-4"
},
{
"activate": true,
"challengeId": "ch-5"
},
]
},
{
"chapter": 1,
"targets": [
{
type: 'user',
recipientId: 4
}
],
"challenge": [
{
"activate": true,
"challengeId": "ch-2"
},
{
"activate": false,
"challengeId": "ch-3"
},
{
"activate": true,
"challengeId": "ch-4"
},
]
},
],
如果输入,我想使用recipientId
数组进行查询
[1,2]
它应该旋转challengeId的交点
预期输出为
[
{"challengeId": "ch-2"},
{"challengeId": "ch-3"}
]
如果输入是[1,2,3]
,它应该返回[]
,因为与此输入没有交集
如果输入是[1,2,4]
也返回
[
{"challengeId": "ch-2"},
]
因为接收方ID 4
的challengeId ch-3
尚未激活
我一直在读$setcrossion
,但它似乎并不能解决我的问题
有什么建议吗?
谢谢。我认为您可以使用此查询非常接近您的结果。你可能只是想清理一下结果
const input = [1,2,4]
db.test.aggregate([
//filter by input array
{ $match: { "targets.recipientId": { $in: input } } },
// Unwind the challenge array
{ $unwind: "$challenge" },
//filter out the non-active ones
{ $match: { "challenge.activate": true } },
//group by challengeId and keep track of the count
{ $group: { _id: "$challenge.challengeId", count: { $sum: 1 } } },
//filter out the challengeId with count < input.length
{ $match: { count: { $gte: input.length } } },
]);
result: {"_id":"ch-2","count":3}
const输入=[1,2,4]
db.test.aggregate([
//按输入数组过滤
{$match:{“targets.recipientId”:{$in:input}},
//解开挑战阵列
{$REWIND:“$CHARGE”},
//过滤掉那些不活跃的
{$match:{“challenge.activate”:true},
//按challengeId分组并跟踪计数
{$group:{{u id:$challenge.challengeId',计数:{$sum:1}},
//过滤掉count
您需要实现一些自定义逻辑,因为$setInterscion
无法接受动态数组字段
到$match
字段收件人ID
筛选挑战的方法是$project
激活:true
按null计数文档总数$group
挑战数组2次,因为我们已将其分组在上面以进行计数$unwind
通过$group
获取挑战计数challengeId
检查文档总数和质询计数是否相同$match
显示必填字段$project
我已经尝试了您的代码,它似乎如我所料是正确的。需要为此测试多个案例。谢谢你的帮助。
db.collection.aggregate([
{ $match: { "targets.recipientId": { $in: [1, 2, 4] } } },
{
$project: {
challenge: {
$filter: {
input: "$challenge",
cond: { $eq: ["$$this.activate", true] }
}
}
}
},
{
$group: {
_id: null,
challenge: { $push: "$challenge" },
count: { $sum: 1 }
}
},
{ $unwind: "$challenge" },
{ $unwind: "$challenge" },
{
$group: {
_id: "$challenge.challengeId",
cCount: { $sum: 1 },
count: { $first: "$count" }
}
},
{ $match: { $expr: { $eq: ["$count", "$cCount"] } } },
{
$project: {
_id: 0,
challengeId: "$_id"
}
}
])