Mongoose查找满足条件的所有子文档

时间:2016-01-18 15:26:29

标签: node.js mongodb mongoose

我有文档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,但它返回所有值。

谢谢!

1 个答案:

答案 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 返回的表达式。