我有文档GradePovider,包含元素:
{
"_id": ObjectId("568a466f2c48409006ab4862"),
"values": [
{
"_id": ObjectId("568a466f2c48409006ab4868"),
"description": "has et delicata moderatius"
},
{
"_id": ObjectId("568a466f2c48409006ab4867"),
"description": "description two"
},
{
"_id": ObjectId("fakeId"),
"description": "description three"
}
]
}
我想通过value._id列表进行搜索。 所以我得到[ObjectId(“568a466f2c48409006ab4868”),ObjectId(“568a466f2c48409006ab4867”)]的搜索回复:
{
"_id": ObjectId("568a466f2c48409006ab4862"),
"values": [
{
"_id": ObjectId("568a466f2c48409006ab4868"),
"description": "has et delicata moderatius"
},
{
"_id": ObjectId("568a466f2c48409006ab4867"),
"description": "description two"
}
]
}
我尝试使用此代码:
gradeModel.GradeProvider.find({
'values._id': {
$in: node.grades
}
}, {
"values.$": true
}, function (err, gradeProviders) {}
此代码仅返回每个gradeProvider的值的第一个匹配项。 我想我需要使用它的聚合。到目前为止,我无法做到这一点。
radeModel.GradeProvider.aggregate([{
$match: {
'values._id': {
$in: node.grades
}
}
}, {
$project: {
providerName: 1,
values: 1
}
}], function (err, gradeProviders) {}
此代码返回正确的GradesProviders,但它返回所有值。
谢谢!
答案 0 :(得分:1)
以下管道适用于您:
var pipeline = [
{
"$match": {
"values._id": { "$in": node.grades }
}
},
{
"$project": {
"providerName": 1,
"values": {
"$setDifference": [
{
"$map": {
"input": "$values",
"as": "el",
"in": {
"$cond": [
{
"$setIsSubset": [
[ "$$el._id" ],
node.grades
]
},
"$$el",
false
]
}
}
},
[false]
]
}
}
}
];
gradeModel.GradeProvider.aggregate(pipeline, function (err, gradeProviders) {});
产生重大影响的运营商是 $setDifference
和 $map
运营商。 $map
运算符本质上创建了一个新的数组字段,该字段通过子表达式中的计算逻辑将数值保存到数组的每个元素。 $setDifference
运算符然后返回一个集合,其中的元素出现在第一个集合中但不出现在第二个集合中;即执行第二组相对于第一组的相对补码。在这种情况下,它将根据条件运算符 $cond
返回最终的values
数组,该数组具有与_id
属性相关的父文档元素。评估运算符 $setIsSubset
返回的表达式。