You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过factory_id关联查询MongoDB工厂文档并嵌入手机结果列表?

如何通过factory_id关联MongoDB中的phone和factory集合并嵌入工厂文档

问题背景

我使用Flask搭配Jinja2模板引擎,通过pymongo操作MongoDB。现有phone和factory两个集合的文档结构如下:

phone集合文档示例

phone = db.get_collection("phone")
{
    "_id": ObjectId("63d8d39206c9f93e68d27206"),
    "brand": "Apple",
    "model": "iPhone XR",
    "year": NumberInt("2016"),
    "image": "https://apple-mania.com.ua/media/catalog/product/cache/e026f651b05122a6916299262b60c47d/a/p/apple-iphone-xr-yellow_1.png",
    "CPU": {
        "manufacturer": "A12 Bionic",
        "cores": NumberInt("10")
    },
    "misc": [
        "Bluetooth 5.0",
        "NFC",
        "GPS"
    ],
    "factory_id": ObjectId("63d8d42b7a4d7a7e825ef956")
}

factory集合文档示例

factory = db.get_collection("factory")
{
    "_id": ObjectId("63d8d42b7a4d7a7e825ef956"),
    "name": "Foxconn",
    "stock": NumberInt("1000")
}

当前我的查询代码为:

models = list(
    phone.find({"brand": brand}, projection={"model": True, "image": True, "factory_id": True})
)

需要实现:通过factory_id获取关联的工厂文档,并将其作为嵌入式文档包含在models列表的每个手机对象中。


解决方案

方案1:使用MongoDB聚合查询($lookup)

利用MongoDB原生的$lookup操作符在数据库层面完成关联,效率更高,适合数据量较大的场景。

pipeline = [
    # 筛选指定品牌的手机
    {"$match": {"brand": brand}},
    # 关联factory集合,匹配factory_id与_id
    {"$lookup": {
        "from": "factory",
        "localField": "factory_id",
        "foreignField": "_id",
        "as": "factory"
    }},
    # 将关联结果的数组转为单个嵌入式文档(一对一关联场景)
    {"$unwind": "$factory"},
    # 指定返回字段(按需调整)
    {"$project": {
        "model": 1,
        "image": 1,
        "factory": 1
    }}
]

models = list(phone.aggregate(pipeline))

说明:

  • $match:和原find逻辑一致,先过滤目标品牌的手机。
  • $lookup:从factory集合中匹配与当前手机factory_id相等的文档,结果会存入factory数组。
  • $unwind:因为每个手机只对应一个工厂,将数组展开为单个对象,方便后续使用。
  • $project:控制最终返回的字段,这里保留手机的型号、图片,以及关联后的工厂文档。

方案2:Python层面手动关联查询

如果不想使用聚合,可通过Python代码手动完成关联,逻辑更直观,适合小数据量场景。

# 1. 查询指定品牌的手机,保留所需字段和factory_id
models = list(
    phone.find({"brand": brand}, projection={"model": True, "image": True, "factory_id": True})
)

# 2. 提取所有factory_id,批量查询工厂并转为字典(以_id为键)
factory_ids = [doc["factory_id"] for doc in models]
factory_map = {f["_id"]: f for f in factory.find({"_id": {"$in": factory_ids}})}

# 3. 将工厂文档嵌入对应手机对象
for doc in models:
    doc["factory"] = factory_map.get(doc["factory_id"])

说明:

  • 第一步按原逻辑获取手机列表。
  • 第二步批量查询所有关联的工厂,用字典存储可以避免多次查询,提升效率。
  • 第三步遍历手机列表,将对应的工厂文档赋值到factory字段中。

内容的提问来源于stack exchange,提问作者Vitalii Mytenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:25:19