我的数据库中有三个集合:

  1. 总代理商
  2. 水果
  3. 工具

我需要链接/查找来自分销商集合的单个文档的集合、成果和工具.

水果和工具中的文档数量在实践中相当有限(每个文档最多5-10个).所以就性能而言,我想这应该没问题.

数据 struct 可从:https://mongoplayground.net/p/AkCarFmdJh1获取

db={
  "总代理商": [
    {
      "name": "Distributor 1",
      // more attributes here
      "children": [
        {
          "name": "Country 1",
          // more attributes here
          "children": [
            {
              "name": "City 1",
              // more attributes here
              "children": [
                {
                  "name": "Shop 1",
                  // more attributes here
                  "children": [
                    {
                      "name": "Fruit 1",
                      // more attributes here
                      "child": "f1"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "水果": [
    {
      "uid": "f1",
      "name": "Fruit 1 Detail",
      "variants": [
        {
          "uid": "v1",
          "name": "Variant 1",
          "工具": [
            "t1",
            "t2"
          ]
        },
        {
          "uid": "v2",
          "name": "Variant 2",
          "工具": [
            "t3",
            "t4"
          ]
        }
      ]
    },
  ],
  "工具": [
    {
      "uid": "t1",
      "name": "Tool 1"
    },
    {
      "uid": "t2",
      "name": "Tool 2"
    },
    {
      "uid": "t3",
      "name": "Tool 3"
    },
    {
      "uid": "t4",
      "name": "Tool 4"
    }
  ]
}
  • 分发服务器集合包含深度嵌套的文档.在最后一层,子"F1"UID应替换为集合"Fruits"中的相应文档.

  • 集合"Fruits"在"Tools"字段中包含集合"Tools"的UID.还应将它们替换为集合"工具"中的相应文件.

  • 最后,我需要一个聚合查询,将所有三个集合链接成一个集合.

我试图用$lookup解决这个问题,但我不确定如何才能到达/链接文档中的更深层次.

GOAL:

{
"name": "Distributor 1",
"children": [
    {
        "name": "Country 1",
        "children": [
            {
                "name": "City 1",
                "children": [
                    {
                        "name": "Shop 1",
                        "children": [
                            {
                                "name": "Fruit 1",
                                "child": {
                                    "uid": "f1",
                                    "name": "Fruit 1 Detail",
                                    "variants": [
                                        {
                                            "uid": "v1",
                                            "name": "Variant 1",
                                            "工具": [
                                                { "uid": "t1", "name": "Tool 1" },
                                                { "uid": "t2", "name": "Tool 2" },
                                            ],
                                        },
                                        {
                                            "uid": "v2",
                                            "name": "Variant 2",
                                            "工具": [
                                                { "uid": "t3", "name": "Tool 3" },
                                                { "uid": "t4", "name": "Tool 4" },
                                            ],
                                        },
                                    ],
                                },
                            }
                        ],
                    }
                ],
            }
        ],
    }
],

}

谢谢你的帮忙!

(我try 了不同的其他方法来对分发服务器集合进行更扁平的建模,但不幸的是,我找不到在应用程序中更容易处理的解决方案.欢迎提出任何建议)

推荐答案

要继续我们的previous discussion强,一种 Select 是:

db.distributors.aggregate([
  {
    "$match": {
      "uid": "d1"
    }
  },
  {
    $lookup: {
      from: "fruits",
      localField: "children.children.children.children.child",
      foreignField: "uid",
      as: "fruits"
    }
  },
  {
    $lookup: {
      from: "tools",
      localField: "fruits.variants.tools",
      foreignField: "uid",
      as: "tools"
    }
  },
  {
    $set: {
      tools: "$$REMOVE",
      fruits: {
        $map: {
          input: "$fruits",
          as: "f",
          in: {
            $mergeObjects: [
              "$$f",
              {
                variants: {
                  $map: {
                    input: "$$f.variants",
                    as: "v",
                    in: {
                      $mergeObjects: [
                        "$$v",
                        {
                          tools: {
                            $map: {
                              input: "$$v.tools",
                              as: "t",
                              in: {
                                $arrayElemAt: [
                                  "$tools",
                                  {
                                    $indexOfArray: [
                                      "$tools.uid",
                                      "$$t"
                                    ]
                                  }
                                ]
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      countriesA: {
        $map: {
          input: "$children",
          as: "country",
          in: {
            $mergeObjects: [
              "$$country",
              {
                children: {
                  $map: {
                    input: "$$country.children",
                    as: "city",
                    in: {
                      $mergeObjects: [
                        "$$city",
                        {
                          children: {
                            $map: {
                              input: "$$city.children",
                              as: "district",
                              in: {
                                $mergeObjects: [
                                  "$$district",
                                  {
                                    children: {
                                      $map: {
                                        input: "$$district.children",
                                        in: {
                                          $arrayElemAt: [
                                            "$fruits",
                                            {
                                              $indexOfArray: [
                                                "$fruits.uid",
                                                "$$this"
                                              ]
                                            }
                                          ]
                                        }
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

看看它在mongoDB playground号公路上是如何工作的

Mongodb相关问答推荐

MongoDB:删除键上有条件的对象元素

除非满足某个条件,否则Mongo是否按日期排序?

当日期和时间在不同键的字符串中时,Mongo 查询过滤今天的数据

Tableau 与 Mongo DB Atlas by MongoDB 的连接缓存问题

Spring Boot 升级后未映射 Mongo 模板结果

在 MongoDB 中加入多个集合

从 kubectl exec 获取返回值到 powershell 脚本

mongodb - 查找包含至少 3 个填充数组的记录

更新 MongoDB 中嵌套实体数组中的属性

查找对象是否在预保存钩子mongoose中更改

无法使用机器 ip 连接到 mongodb

具有最佳插入/秒性能的数据库?

MongoDB:按标签获取文档

在 MongoDB 中创建简短、唯一的对象 ID

有没有办法将python对象直接存储在mongoDB中而不序列化它们

如何使用node.js http服务器从mongodb返回大量行?

MongoDB的数据库管理工具

MongoDB MapReduce - 发出一个键/一个值不调用reduce

Mongoose:查询starts with

使用 Mongoose ORM 的杀手锏是什么?