【问题标题】:Mongo create new field by mapping value from one field to value in a field in another collectionMongo通过将一个字段中的值映射到另一个集合中的字段中的值来创建新字段
【发布时间】:2021-08-01 10:30:51
【问题描述】:

我有一个集合 c1,其值类似于 {'Race': 'blck'},我想使用另一个集合 c2,其字段为 {'raw': 'blck', 'mapped_race': 'black'},以使用 {'Race_Standardized': 'black'} 之类的新字段更新 c1 中的文档。这可以通过将 c1 中 Race 的值与 c2 中文档的原始值相匹配来实现。

更新将使 c1 文档具有字段 {'Race': 'blck', 'Race_Standardized': black'}

如何在聚合管道中执行此操作? (我在 PyMongo 工作。)

【问题讨论】:

  • 聚合管道是不可能的,它需要 2 个单独的查询从 c2 中查找并在 c1 中更新。

标签: python mongodb mongodb-query aggregation-framework pymongo


【解决方案1】:

由于 Mongo 是一个 nosql 数据库,因此没有像我们在关系数据库中那样的连接。然而,聚合管道中的 $lookup 功能克服了这一点。我还没有在 pymongo 框架中尝试这个,但是在 mongo 中,你必须使用 $lookup 、 $unwind 和 $out 的组合来更新字段。 $lookup 就像 SQL 世界中的左连接并返回一个数组 - 我们必须使用 $unwind 来获取特定字段,然后使用 $out 来更新或写入新集合。我发现此链接很有帮助 [https://developer.mongodb.com/community/forums/t/update-a-collection-field-based-on-another-collection/4875]

【讨论】:

    【解决方案2】:

    应该这样做:

    db.c1.aggregate([
        {
            $lookup: {
                from: "c2",
                localField: "Race",
                foreignField: "raw",
                as: "Race_Standardized"
            }
        },
        {
            $set: {
                Race_Standardized: {
                    $first: "$Race_Standardized.mapped_race"
                }
            }
        },
        {
            $out: "c1"
        }
    ])
    

    但请记住,$out 阶段将覆盖 c1 集合。

    【讨论】:

    • 如果您使用的是 MongoDB 4.2+,请使用 $merge 而不是 $out
    【解决方案3】:

    查询c2集合并在客户端迭代文档以为c1构建批量写入操作可能更有效:

    updates = []
    for doc in db.c2.find({}):
       updates.append(pymongo.UpdateMany({'Race':doc.get('raw')},{'$set':{'Race_Standardized':doc.get('mapped_race')}}))
    result = db.c1.bulk_write(updates)
    

    【讨论】:

      猜你喜欢
      • 2017-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      相关资源
      最近更新 更多