【问题标题】:Mongoose aggregate pipeline joining field in subdocument子文档中的 Mongoose 聚合管道连接字段
【发布时间】:2019-10-05 09:20:57
【问题描述】:

我有以下 3 个收藏:

1. runs:
{
  "_id":ObjectId("5cda6191e1b7c889e0442dff"),
  "status":1,
  "runName":"My Run Test 01"
}
2. runsets:
{
  "_id":ObjectId("5cda6191e1b7c889e0442e01"),
  "_run":ObjectId("5cda6191e1b7c889e0442dff"),
  "config": "Config 1",
  "suites":[{
    "_id":"ObjectId(5cda6191e1b7c889e0442e03"),
    "suiteid":ObjectId("5c748822e0ae897b0c312719"),
    "suitename":"My Test Suite 1",
    "tests":[{
      "_id":ObjectId("5cda6191e1b7c889e0442e04"),
      "testid":ObjectId("5c746708cefe8d75349b6486"),
      "testname":"Buy items with validations 002"
    }]
  }]
}
3. testresults:
{
  "_id":ObjectId("5cda65f6e494c61d30cee49c"),
  "_runset":ObjectId("5cda6191e1b7c889e0442e01"),
  "_test":"ObjectId(5c746708cefe8d75349b6486)",
  status: 1
}

我想将这 3 个集合聚合成一个文档,如下所示:

[
  {
    "_id": "5cda6191e1b7c889e0442dff",
    "status": 1,
    "runName": "My Run Test 01",
    "runsetitems": [
      {
        "_id": "5cda6191e1b7c889e0442e01",
        "_run": "5cda6191e1b7c889e0442dff",
        "_config": "Config 1",
        "suites": [
          {
            "_id": "5cda6191e1b7c889e0442e03",
            "suiteid": "5c748822e0ae897b0c312719",
            "suitename": "My Test Suite 1",
            "suitedesc": "My Test Suite 1 Description",
            "tests": [
              {
                "_id": "5cda6191e1b7c889e0442e04",
                "testid": "5c746708cefe8d75349b6486",
                "testname": "Buy items with validations 002",
                "testdesc": "Buy more than one items and validate price",
                "testitem": {
                  "status": 1
                }
              }
            ]
          }
        ]
      }
    ]
  }
]
const run = await RunModel.aggregate([
    {$match: {'_user': mongoose.Types.ObjectId('5c6c997de0a0b446e87c3389')}},
    {
      $lookup:
      {
        from: 'runsets',
        let: { runid: '$_id' },
        pipeline: [
          {
            $match:
            {
              $expr:
              {
                $eq: ['$_run', '$$runid']
              }
            }
          }, {
            $lookup:
            {
              from: 'testresults',
              let: { runsetid: '$_id', testid: '$suites.tests.testid' },
              pipeline: [
                {
                  $match:
                  {
                    $expr:
                    {
                      $and:
                        [
                          { $eq: [ '$_test',  '$$testid' ] },
                          { $eq: [ '$_runset',  '$$runsetid' ] }
                        ]
                    }
                  }
                },
                {$project : { 'status': 1 }}
              ],
              as: 'suites.tests.testitem'
            }
          }         
        ],
        as: 'runsetitems'
      }
    },
    {$project : { '_id': 1 , 'runName': 1, 'runDesc': 1, 'status': 1, 'submitTime': 1, 'endTime': 1, 'runsetitems': 1, 'projectitem.projectName': 1 } }
])

但是有两个问题:

首先,加入 _test 和 suites.tests.testid 不起作用。包含时返回 testitem:[]。

如果我删除了上面提到的连接,testitem 会返回,但它会产生另一个问题。它将删除测试的属性“testname”和“testdesc”,如下所示:

"tests": {
  "testitem": [
    {
       "_id": "5cda67d4e494c61d30cee5d6",
       "status": 1
    }
  ]
}

任何建议将不胜感激!

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    你有 testid 嵌套在数组的数组中。您需要先$unwindsuitessuites.tests 然后$group 来管理相同的订单。

    db.runs.aggregate([
      { "$lookup": {
        "from": "runsets",
        "let": { "runid": "$_id" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": ["$_run", "$$runid"] }}},
          { "$unwind": "$suites" },
          { "$unwind": "$suites.tests" },
          { "$lookup": {
            "from": "testresults",
            "let": { "runsetid": "$_id", "testid": "$suites.tests.testid" },
            "pipeline": [
              { "$match": {
                "$expr": {
                  "$and": [
                    { "$in": ["$_test", "$$testid"] },
                    { "$eq": ["$_runset", "$$runsetid"] }
                  ]
                }
              }},
              { "$project": { "status": 1 }}
            ],
            "as": "suites.tests.testitem"
          }},
          { "$unwind": "$suites.tests.testitem" },
          { "$group": {
            "_id": { "_id": "$_id", "suiteid": "$suites._id" },
            "_run": { "$first": "$_run" },
            "suiteid": { "$first": "$suites.suiteid" },
            "suitename": { "$first": "$suites.suitename" },
            "config": { "$first": "$config" },
            "config": { "$first": "$config" },
            "tests": { "$push": "$suites.tests" }
          }},
          { "$group": {
            "_id": "$_id._id",
            "_run": { "$first": "$_run" },
            "config": { "$first": "$config" },
            "suites": {
              "$push": {
                "_id": "$_id.suiteid",
                "tests": "$tests",
                "suiteid": "$suiteid",
                "suitename": "$suitename"
              }
            }
          }}
        ],
        "as": "runsetitems"
      }},
      { "$project": {
        "_id": 1,
        "runName": 1,
        "runDesc": 1,
        "status": 1,
        "submitTime": 1,
        "endTime": 1,
        "runsetitems": 1,
        "projectitem.projectName": 1
      }}
    ])
    

    MongoPlayground

    【讨论】:

    • 这就像一个魅力,完全解决了我提出的两个问题。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 2020-12-05
    • 2015-05-01
    • 2021-06-29
    • 2020-08-02
    • 2020-11-14
    • 2014-10-10
    • 2023-03-15
    相关资源
    最近更新 更多