mongoosefind满足条件的所有子文档
我有文档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列表进行search。 所以我得到了[ObjectId(“568a466f2c48409006ab4868”),ObjectId(“568a466f2c48409006ab4867”)]的search响应:
{ "_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,但它返回所有的值。
谢谢 !
以下pipe道应该为你工作:
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
操作符实质上创build了一个新的数组字段,该数组字段将值作为评估逻辑的结果保存在数组的每个元素的子expression式中。 $setDifference
操作符然后返回一个集合,其中元素出现在第一个集合中,但不在第二个集合中; 即相对于第一组执行第二组的相对补充。 在这种情况下,它将通过基于条件运算符$cond
的_id
属性返回具有与父文档无关的元素的最终values
数组,该条件运算符$cond
将计算运算符$setIsSubset
返回的expression式。