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式。