Mongo DB:如何从一个集合中复制文档并将其作为字段添加到另一个集合中的相关文档中?

时间:2021-02-09 21:28:14

标签: database mongodb mongodb-query aggregation-framework

数据库中有 2 个集合:

产品

plugins:
    - search:
        lang: en

活动

{
   "_id":"unique_product_id",
   "name":"Product 1",
   "price":50
}

其中 { "_id":"unique_event_id_1", "product_id":"unique_product_id", "action":"created" }, { "_id":"unique_event_id_2", "product_id":"unique_product_id", "action":"updated" } 集合包含与来自 Events 集合的文档相关联的文档。 我的想法只是将文档从 Products 集合注入 Events,结果 Products 将如下所示:

产品

Products

我想了解是否可以将其作为 { "_id":"unique_product_id", "name":"Product 1", "price":50, "events":[ { "_id":"unique_event_id", "product_id":"unique_product_id_1", "action":"created" }, { "_id":"unique_event_id", "product_id":"unique_product_id_1", "action":"updated" } ] } 的一部分实施?

我需要找到类似 Mongodb Aggregation framework 的东西,它接受聚合管道返回的文档并将它们写入指定的集合,但我不需要写入特定集合,而是写入特定集合的特定文档收藏。

1 个答案:

答案 0 :(得分:1)

从 MongoDB 4.4 开始,$merge 可以输出到正在聚合的同一个集合:

db.products.aggregate([       
   { /**
    * from: The target collection.
    * localField: The local join field.
    * foreignField: The target join field.
    * as: The name for the results.
    * pipeline: The pipeline to run on the joined collection.
    * let: Optional variables to use in the pipeline field stages.
    */
   $lookup: {
     from: 'events',
     localField: '_id',
     foreignField: 'product_id',
     as: 'events'
   }},
   {/**
    * into: The target collection.
    * on: Fields to  identify.
    * whenMatched: Action for matching docs.
    * whenNotMatched: Action for non-matching docs.
    */
   $merge: {
     into: 'products',
     on: "_id",
     whenMatched: 'merge',
     whenNotMatched: 'insert'
   }}
])

注意:当 $merge 输出到正在聚合的同一个集合时,文档可能会被多次更新,或者操作可能会导致无限循环。更多详情请点击https://docs.mongodb.com/manual/reference/operator/aggregation/merge/#merge-behavior-same-collection

如果是一次性更新,您可以通过添加初始过滤器作为第一阶段来保护管道,以确保文档只更新一次:

{ $match: { events: { $exists: false } }