$ lookup管道阶段的使用存在问题:性能问题和使用情况

时间:2018-10-25 09:19:35

标签: mongodb

这是我第一次在这里发布信息,希望我的请求能按原样进行删节,但是如果没有,我很抱歉。

我是mongodb的新手,我正在尝试对名为“ builds”的集合执行$ lookup操作,该集合存储了约15.000个文档。 这是存储在此集合中的文档的结构:

{ 
    "_id" : ObjectId("5bc4d54c4d92ca946f67a8f4"), 
    "branch" : "master", 
    "build_number" : 11018, 
    "change" : "390494", 
    "commit" : "241a12e27baf40aa874687d289a2b5cc02d3d143", 
    "directory_size" : 621485449, 
    "duration" : "2035435", 
    "fingerprints" : { 
        "commit" : "266e3227d2d68b309998f963bd46653b", 
        "legacyTreeish" : "e14967681cf356d67b2480704d3ed6bf", 
        "subtree" : "45fb7898dc1cf0c7ffda3e9e03797953", 
        "treeish" : "f190542db721000900d33e77090e3dd3" 
    }, 
    "job" : "MASTER_PROD/UPLANE/L2-PS/BUILD.bbp", 
    "patchset" : "2", 
    "pipeline" : "gate", 
    "project" : "MN/5G/NB/gnb", 
    "release" : "18A", 
    "result" : "SUCCESS", 
    "retries" : 0, 
    "reused" : 0, 
    "server" : "es-si-os-ohn-65-5g-ci-common-6d9", 
    "startTime" : "1531304202954", 
    "timestamp" : "1531304202953", 
    "uuid" : "f51420141dc94a03a58bbd28fa35f6c9", 
    "voting" : true 
}

编辑:我正在尝试使用mongo shell执行我的请求。

我正在尝试执行以下请求以查找文档:

  1. 将结果键设置为“成功”,并将管道键设置为“检查”。

  2. 例如至少存在一个文档,它们具有相同的管道,作业,变更和补丁集,并且结果与“ SUCCESS”不同。

这是我的要求:

db.builds.aggregate(
    [
        { $match:   { pipeline: "check", result: "SUCCESS" } },
        { $lookup:  { 
                from: "builds", 
                let: { change: "$change", patchset: "$patchset", result: "$result", job: "$job", pipeline: "$pipeline" }, 
                pipeline: [
                    { $match: { 
                        $expr: { 
                            $and: 
                                [
                                    { $eq: [ "$$change", "$change"]},
                                    { $eq: [ "$$patchset", "$patchset"]},
                                    { $eq: [ "$$pipeline", "check" ]},
                                    { $eq: [ "$$job", "$job" ]},
                                    { $ne: [ "$$result", "SUCCESS" ]}
                                ]         
                        }
                    }
                }    
                ],
                as: "unstables"
            } 
        },
        { $project: { unstables: 1} }
    ]
)

此请求有两个问题:

  1. 当我使用上一个项目操作时需要花费几分钟,而当我不使用它时只需花费几秒钟。对于集合中的以下每个键,我确实有一个索引:更改,补丁集,作业,管道和结果。我想我做错了什么,但我无法确定是什么。

  2. 由$ lookup管道阶段填充的“不稳定”数组始终为空。据告诉我有关集合中数据的信息,事实并非如此。我想我对$ lookup操作的使用是错误的,但我不知道为什么。

如果有人能指出正确的方向来解决这个麻烦的请求,我将不胜感激!在此先感谢:)

1 个答案:

答案 0 :(得分:0)

您在流水线阶段使用$$犯了一个错误:$$代表“基本”集合,$代表“联合”集合。在管道和结果上使用$ match进行过滤时,

{ $eq: [ "$$change", "$change"]},
{ $eq: [ "$$patchset", "$patchset"]},
{ $eq: [ "$$pipeline", "check" ]},      ===> always true
{ $eq: [ "$$job", "$job" ]},
{ $ne: [ "$$result", "SUCCESS" ]}       ===> always false

这是正确的语法:

{ $eq: [ "$$change", "$change"]},
{ $eq: [ "$$patchset", "$patchset"]},
{ $eq: [ "$pipeline", "check" ]},    // or { $eq: [ "$pipeline", "$$pipeline" ]}
{ $eq: [ "$$job", "$job" ]},
{ $ne: [ "$result", "SUCCESS" ]}     // or { $ne: [ "$result", "$$result" ]}

但是您可以通过转换您的需求而无需使用$ lookup阶段来达到相同的目的: 您需要使用

构建
  • 相同的更改,补丁集,作业
  • 其中管道=“检查”
  • 至少有一个“ SUCCESS”和一个其他值作为结果。

您可以使用以下方法执行此操作:

db.builds.aggregate([
  {
    $match: {
      pipeline: "check",

    }
  },
  {
    $group: {
      _id: {
        change: "$change",
        patchset: "$patchset",
        job: "$job",
        pipeline: "$pipeline"
      },
      builds: {
        $push: "$$ROOT"
      },
      resultset: {
        $addToSet: "$result"
      }
    }
  },
  {
    $match: {
      $expr: {
        $and: [
          {
            $gt: [
              {
                $size: "$resultset"
              },
              1
            ]
          },
          {
            $in: [
              "SUCCESS",
              "$resultset"
            ]
          }
        ]
      }
    }
  }
])

您可以here对其进行测试。希望对您有帮助