【问题标题】:mongodb aggregate lookup with a query带有查询的mongodb聚合查找
【发布时间】:2020-11-23 08:16:14
【问题描述】:

我有以下值的集合:

报告

{
    "_id": { "$oid": "5f05e1d13e0f6637739e215b" },
    "testReport": [
      {
        "name": "Calcium",
        "value": "87",
        "slug": "ca",
        "details": {
          "description": "description....",
          "recommendation": "recommendation....",
          "isNormal": false
        }
      },
      {
        "name": "Magnesium",
        "value": "-98",
        "slug": "mg",
        "details": {
          "description": "description....",
          "recommendation": "recommendation....",
          "isNormal": false
        }
      }
    ],
    "patientName": "Patient Name",
    "clinicName": "Clinic",
    "gender": "Male",
    "bloodGroup": "A",
    "createdAt": { "$date": "2020-07-08T15:10:09.612Z" },
    "updatedAt": { "$date": "2020-07-08T15:10:09.612Z" }
  },

设置

{
    "_id": { "$oid": "5efcba7503f4693d164e651d" },
    "code": "Ca",
    "codeLower": "ca",
    "name": "Calcium",
    "valueFrom": -75,
    "valueTo": -51,
    "treatmentDescription": "description...",
    "isNormal": false,
    "gender": "",
    "recommendation": "recommendation...",
    "createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
    "updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
  },
  {
    "_id": { "$oid": "5efcba7503f4693d164e651e" }, // <=== should find this for Calcium
    "code": "Ca",
    "codeLower": "ca",
    "name": "Calcium",
    "valueFrom": 76,
    "valueTo": 100,
    "treatmentDescription": "description...",
    "isNormal": false,
    "gender": "",
    "recommendation": "recommendation...",
    "createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
    "updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
  },
  {
    "_id": { "$oid": "5efcba7603f4693d164e65bb" },  // <=== should find this for Magnesium
    "code": "Mg",
    "codeLower": "mg",
    "name": "Magnesium",
    "valueFrom": -100,
    "valueTo": -76,
    "treatmentDescription": "description...",
    "isNormal": false,
    "gender": "",
    "recommendation": "recommendation...",
    "createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
    "updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
  },
  {
    "_id": { "$oid": "5efcba7503f4693d164e6550" },
    "code": "Mg",
    "codeLower": "mg",
    "name": "Magnesium",
    "valueFrom": 76,
    "valueTo": 100,
    "treatmentDescription": "description...",
    "isNormal": false,
    "gender": "",
    "recommendation": "recommendation...",
    "createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
    "updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
  }

我想从 reports 集合中搜索 value 并检查该值是否在 setups 集合的范围内并返回 _id 并将返回的 _ids 添加到 reports 集合的 setupIds 字段中。

我尝试了以下聚合框架:

db.reports.aggegrate([
    {
      '$match': {
        '_id': new ObjectId('5f05e1d13e0f6637739e215b')
      }
    }, {
      '$lookup': {
        'from': 'setups', 
        'let': {
          'testValue': '$testReport.value', 
          'testName': '$testReport.name'
        }, 
        'pipeline': [
          {
            '$match': {
              '$expr': {
                {
                    '$and': [
                      {
                        '$eq': [
                          '$name', '$$testName'
                        ]
                      }, {
                        '$gte': [
                          '$valueTo', '$$testValue'
                        ]
                      }, {
                        '$lte': [
                          '$valueFrom', '$$testValue'
                        ]
                      }
                    ]
                  }
              }
            }
          }
        ], 
        'as': 'setupIds'
      }
    }
  ])

此查询未找到预期结果。

这是我想要的更新后的报告集合:

{
    "_id": { "$oid": "5f05e1d13e0f6637739e215b" },
    "setupIds": [{ "$oid": "5efcba7503f4693d164e651e" }, { "$oid": "5efcba7603f4693d164e65bb" }],  // <=== Here, array of the ObjectId (ref: "Setups")
    "patientName": "Patient Name",
    "clinicName": "Clinic",
    "gender": "Male",
    "bloodGroup": "A",
    "createdAt": { "$date": "2020-07-08T15:10:09.612Z" },
    "updatedAt": { "$date": "2020-07-08T15:10:09.612Z" }
  },

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    你可以尝试如下

    [{
        $match: {
            _id: ObjectId('5f05e1d13e0f6637739e215b')
        }
    }, {
        $unwind: {
            path: "$testReport"
        }
    }, {
        $lookup: {
            from: 'setup',
            'let': {
                testValue: {
                    $toInt: '$testReport.value'
                },
                testName: '$testReport.name'
            },
            pipeline: [{
                $match: {
                    $expr: {
                        $and: [{
                                "$eq": [
                                    "$name",
                                    "$$testName"
                                ]
                            },
                            {
                                "$gte": [
                                    "$valueTo",
                                    "$$testValue"
                                ]
                            },
                            {
                                "$lte": [
                                    "$valueFrom",
                                    "$$testValue"
                                ]
                            }
                        ]
                    }
                }
            }],
            as: 'setupIds'
        }
    }, {
        $group: {
            _id: "$_id",
            patientName: {
                $first: "$patientName"
            },
            clinicName: {
                $first: "$clinicName"
            },
            gender: {
                $first: "$gender"
            },
            bloodGroup: {
                $first: "$bloodGroup"
            },
            createdAt: {
                $first: "$createdAt"
            },
            updatedAt: {
                $first: "$updatedAt"
            },
            setupIds: {
                $addToSet: "$setupIds._id"
    
            }
        }
    }, {
        $addFields: {
            setupIds: {
                $reduce: {
                    input: "$setupIds",
                    initialValue: [],
                    in: {
                        $setUnion: ["$$this", "$$value"]
                    }
                }
    
    
            }
        }
    }]
    

    工作Mongo playground

    【讨论】:

    • 谢谢。它按预期工作。如果您不介意,如果 reports 集合说 anotherTestReport 类似于 testReport,是否可以使用多个 unwind 和 @ 987654326@ 并将新 ID 添加到 setupIds?下次我尝试运行相同的查询,但它替换了所有 id。
    • 我希望,这是可能的。但我没有正确理解你的问题。如果问题与此不相似,请在此处发布新问题并评论 url,否则编辑此问题
    • 这里是 Mongo Playground 的链接:mongoplayground.net/p/tLlHDPNukJM 我已经更新了配置部分。
    • 会检查并通知您
    • 你能检查一下这个mongoplayground.net/p/27uYyVZx76a你可以使用$unwind 和使用$or(我不知道位置是否正确)
    猜你喜欢
    • 1970-01-01
    • 2021-01-11
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2019-06-18
    • 2017-03-18
    相关资源
    最近更新 更多