【问题标题】:Mongoose find All subdocuments satisfying a conditionMongoose 查找所有满足条件的子文档
【发布时间】:2016-04-23 20:01:01
【问题描述】:

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

谢谢!

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案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 评估由运营商 $setIsSubset.

    【讨论】:

    • 是的,我只有一点 "$setIsSubset": [ [ "$$el._id" ], node.grades ] 对于两个相同的 ObjectId (但不是同一个实例)没有返回 true .知道如何处理这种情况吗?除了在 ObjectId 的数组上应用 toString 之外?
    猜你喜欢
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2018-06-12
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    相关资源
    最近更新 更多