当前位置: 首页 > 知识库问答 >
问题:

跨不同集合的聚合(外键)--MongoDB聚合

桂鑫鹏
2023-03-14

第一个名为origin的文档包含以下文档(不包括_id):

[
  {
    "Id": "1",
    "Level1": [
      {
        "Id": "1.1",
        "Level2": [
          {
            "Level3": {
              "Id": "1.1.1",
              "Name": "name 1.1.1"
            }
          },
          {
            "Level3": {
              "Id": "1.1.2",
              "Name": "name 1.1.2"
            }
          }
        ]
      },
      {
        "Id": "1.2",
        "Level2": [
          {
            "Level3": {
              "Id": "1.2.1",
              "Name": "name 1.2.1"
            }
          },
          {
            "Level3": {
              "Id": "1.2.2",
              "Name": "name 1.2.2"
            }
          }
        ]
      }
    ]
  },
  {
    "Id": "2",
    "Level1": [
      {
        "Id": "2.1",
        "Level2": [
          {
            "Level3": {
              "Id": "2.1.1",
              "Name": "name 2.1.1"
            }
          },
          {
            "Level3": {
              "Id": "2.1.2",
              "Name": "name 2.1.2"
            }
          }
        ]
      },
      {
        "Id": "2.2",
        "Level2": [
          {
            "Level3": {
              "Id": "2.2.1",
              "Name": "name 2.2.1"
            }
          },
          {
            "Level3": {
              "Id": "2.2.2",
              "Name": "name 2.2.2"
            }
          }
        ]
      }
    ]
  }
]

第二个集合名为destination,具有以下文档:

[
  {
    "Id": "f1",
    "Level1": {
      "Level2": {
        "Id": "1.1.1",
        "Name": "name 1.1.1"
      }
    }
  },
  {
    "Id": "f2",
    "Level1": {
      "Level2": {
        "Id": "1.1.2",
        "Name": "name 1.1.2"
      }
    }
  },
  {
    "Id": "f3",
    "Level1": {
      "Level2": {
        "Id": "1.2.1",
        "Name": "name 1.2.1"
      }
    }
  },
  {
    "Id": "f4",
    "Level1": {
      "Level2": {
        "Id": "1.2.2",
        "Name": "name 1.2.2"
      }
    }
  },
  {
    "Id": "f5",
    "Level1": {
      "Level2": {
        "Id": "2.1.1",
        "Name": "name 2.1.1"
      }
    }
  },
  {
    "Id": "f6",
    "Level1": {
      "Level2": {
        "Id": "2.1.2",
        "Name": "name 2.1.2"
      }
    }
  },
  {
    "Id": "f7",
    "Level1": {
      "Level2": {
        "Id": "2.2.1",
        "Name": "name 2.2.1"
      }
    }
  },
  {
    "Id": "f8",
    "Level1": {
      "Level2": {
        "Id": "2.2.2",
        "Name": "name 2.2.2"
      }
    }
  }
]

level1.id=“1.1”上的Origin

预期的结果是:

[
  {
    "Id": "f1",
    "Level1": {
      "Level2": {
        "Id": "1.1.1",
        "Name": "name 1.1.1"
      }
    }
  },
  {
    "Id": "f2",
    "Level1": {
      "Level2": {
        "Id": "1.1.2",
        "Name": "name 1.1.2"
      }
    }
  }
]

如何使用聚合查询来实现这一点?

共有1个答案

谢俊英
2023-03-14

在MongoDB中,为了聚合来自不同集合的数据,我们使用$lookup

我已经按照你的要求做了查找查询。

db.origin.aggregate([
  {
    $unwind:"$Level1"
  },
  {
    $unwind:"$Level1.Level2"
  },
  {
    $lookup:{
      from:"destination",
      let:{
        "level":"$Level1.Level2.Level3"
      },
      pipeline:[
        {
          $match:{
            $expr:{
              $eq:[
                "$Level1.Level2","$$level"
              ]
            }
          }
        }
      ],
      as:"lookups"
    }
  },
  {
    $unwind:{
      path:"$lookups",
      preserveNullAndEmptyArrays:true
    }
  }
]).pretty()

为了在输出中显示所需的字段,可以使用$project。更多信息请点击此处阅读。

db.destination.aggregate([
  {
    $lookup:{
      from:"origin",
      let:{
        "level":"$Level1.Level2"
      },
      pipeline:[
        {
          $unwind:"$Level1"
        },
        {
          $unwind:"$Level1.Level2"
        },
        {
          $match:{
            $expr:{
              $eq:[
                "$Level1.Level2.Level3","$$level"
              ]
            }
          }
        }
      ],
      as:"lookups"
    }
  },
  {
    $unwind:{
      path:"$lookups",
      preserveNullAndEmptyArrays:true
    }
  },
  {
    $project:{
      "Id":1,
      "Level1.Level2":"$lookups.Level1.Level2.Level3"
    }
  }
]).pretty()
[
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f67"),
                "Id" : "f1",
                "Level1" : {
                        "Level2" : {
                                "Id" : "1.1.1",
                                "Name" : "name 1.1.1"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f68"),
                "Id" : "f2",
                "Level1" : {
                        "Level2" : {
                                "Id" : "1.1.2",
                                "Name" : "name 1.1.2"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f69"),
                "Id" : "f3",
                "Level1" : {
                        "Level2" : {
                                "Id" : "1.2.1",
                                "Name" : "name 1.2.1"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f6a"),
                "Id" : "f4",
                "Level1" : {
                        "Level2" : {
                                "Id" : "1.2.2",
                                "Name" : "name 1.2.2"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f6b"),
                "Id" : "f5",
                "Level1" : {
                        "Level2" : {
                                "Id" : "2.1.1",
                                "Name" : "name 2.1.1"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f6c"),
                "Id" : "f6",
                "Level1" : {
                        "Level2" : {
                                "Id" : "2.1.2",
                                "Name" : "name 2.1.2"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f6d"),
                "Id" : "f7",
                "Level1" : {
                        "Level2" : {
                                "Id" : "2.2.1",
                                "Name" : "name 2.2.1"
                        }
                }
        },
        {
                "_id" : ObjectId("5e92196a3a5a7fc48b644f6e"),
                "Id" : "f8",
                "Level1" : {
                        "Level2" : {
                                "Id" : "2.2.2",
                                "Name" : "name 2.2.2"
                        }
                }
        }
]
 类似资料:
  • 我在mongodb中的聚合有点问题; 收藏uczelna: 我的合计: 我想找到所有的医生(doktorzy)妇女(名字的最后一个字母a)在一所学校(uczelna)。imie(姓名) 告诉我我做错了什么,谢谢

  • 我不熟悉Spring和Mongo。我正在使用Spring Batch获取一些报告。我的查询需要一些MongoItemReader不支持的聚合,所以我根据下面的stackoverflow链接扩展了该类。 如何在Spring批处理中使用MongoItemReader聚合查询 但我的聚合有点问题。我制作的聚合在mongoDB中运行良好,但无法将其转换为Spring mongo聚合。 MongoDb聚合按

  • 我使用Nodejs和MongoDB与expressjs和mongoose库,创建一个具有用户、文章和评论模式的博客API。下面是我使用的模式。

  • 主要内容:aggregate() 方法,管道MongoDB 中的聚合操作用来处理数据并返回计算结果,聚合操作可以将多个文档中的值组合在一起,并可对数据执行各种操作,以返回单个结果,有点类似于 SQL 语句中的 count(*)、group by 等。 aggregate() 方法 您可以使用 MongoDB 中的 aggregate() 方法来执行聚合操作,其语法格式如下: db.collection_name.aggregate(aggr

  • 并给我带来这些结果: {“_id”:{“name”:“city1”},“count”:212} {“_id”:{“name”:“city2”},“count”:1200} https://hexdocs.pm/mongodb/readme.html#贡献 提前谢了。

  • 我有一种情况,我需要根据一个数组值执行一个group by操作,该数组值将字段值的出现次数相加。然后对计数进行过滤,并准备结果,以便根据条件显示结果。从本质上讲,文档被转换回如果您只使用find函数就会呈现的方式。由于matchedDocuments数组中收集的项的数量,我遇到了临时文档太大的问题。任何关于如何改进这一点的建议都将是有益的。 以下是一些示例文档和基于上述标准的预期结果: