首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于性能的MongoDB $lookup (聚合)和$project

基于性能的MongoDB $lookup (聚合)和$project
EN

Stack Overflow用户
提问于 2022-10-21 08:31:08
回答 1查看 41关注 0票数 3

嘿,我对大型聚合mongo脚本做了一些性能测试,当我将项目行从

代码语言:javascript
复制
           "$lookup":{
        "from": "metrics",
        "as":   "metrics",
        "let": {"userId": "$_id"},
        "pipeline": {
        {"$match":{"$expr": {"$in": {"$$userId","$ownerIds"}}}},
  ----> {"$project": {"fieldName": 1, "ownerIds": 1, "auth0Cache": 1}},
},
},

代码语言:javascript
复制
      "$lookup":{
        "from": "metrics",
        "as":   "metrics",
        "let": {"userId": "$_id"},
        "pipeline": {
---->   {"$project": {"fieldName": 1, "ownerIds": 1, "auth0Cache": 1}},
        {"$match":{"$expr": {"$in": {"$$userId","$ownerIds"}}}},
     
},
},

它让表演跳起来了。它跑得快2-3倍。当您限制数据时,因为这个集合很大,它应该运行得更快,这是有意义的,但是我没有找到任何关于它的文档。有人知道为什么这是一个重要的变化,并能向我解释为什么会发生,并提供更多的信息吗?提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2022-10-21 13:26:03

目前问题中的资料太少,无法得出任何明确的结论。作为@Tornike Skhulukhia在评论中建议,共享用于此聚合的完整.explain("executionStats")输出将使我们更清楚地了解可能发生的事情。

基于共享的小部分,这里有一件事情看起来很可疑,那就是使用花括号({})来定义pipeline。通常,这是一个数组,允许提供一系列的聚合阶段。的确是蒙古操场在使用花括号时会抱怨。在创建问题时,这可能只是一个复制/粘贴错误,特别是因为$in列表中有相同的错误,但当然,如果您使用的驱动程序/语言将pipeline压缩到可能有助于解释正在发生的事情的第一阶段。注意,在某些情况下,可以将单个文档(表示唯一的聚合阶段)传递给.aggregate()方法本身,而不是通常的数组,这里有一个小小的操场示范证明这种结构在那里成功运行。因此,这样的诡计并不是不可能的,更多的信息将是有帮助的。

如果我在代码之间读一点,听起来就像是在努力提高某些聚合管道的性能。尽管没有足够的信息可以肯定地说什么,但我建议简化这个$lookup的定义。现有阶段的定义如下:

代码语言:javascript
复制
  {
    "$lookup": {
      "from": "metrics",
      "as": "metrics",
      "let": {
        "userId": "$_id"
      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$in": [
                "$$userId",
                "$ownerIds"
              ]
            }
          }
        },
        {
          "$project": {
            "fieldName": 1,
            "ownerIds": 1,
            "auth0Cache": 1
          }
        }
      ],
      
    }
  }

这可以简化为使用localField/foreignField语法,至少如下所示:

代码语言:javascript
复制
  {
    "$lookup": {
      "from": "metrics",
      "as": "metrics",
      localField: "_id",
      foreignField: "ownerIds",
      "pipeline": [
        {
          "$project": {
            "fieldName": 1,
            "ownerIds": 1,
            "auth0Cache": 1
          }
        }
      ],
      
    }
  }

在此之前之后的操场演示。

此更改可能允许数据库更好地利用metrics集合上的metrics索引。

我要提到的最后一件事是关于$project的使用。的确,一般来说,尽早减少正在处理的数据量是个好主意。但是,投影的使用应该保留在管道(或子管道)的末尾,这只是将结果转换成所需格式的一种方法。数据库将自动计算出管道所需的字段,并尽可能地优化限制数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74150870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档