【问题标题】:Update document with aggregation pipeline with $lookup使用 $lookup 使用聚合管道更新文档
【发布时间】:2022-01-17 22:06:46
【问题描述】:

我有一个产品集合,其中包含字段 -userId、referenceProductId、 我想将新字段buyerUserId添加到其值将等于userId的所有文档中,以获取_id等于referenceProduct_id的文档 例如-对于以下 2 文档

{
  "_id": { "$oid": "61ded34c1e7007b17a86f889" },
  
  "userId": { "$oid": "6190b06b113314ad2183db09" },
  
  "referenceProductId": { "$oid": "61ded15fdd1363aa1ce09c55" }
  
}

{
    "_id": { "$oid": "61ded15fdd1363aa1ce09c55" },
    
    "userId": { "$oid": "6190b06b113314ad2183db09" },
    
    "referenceProductId": { "$oid": "61ded34c1e7007b17a86f889" }
    
  }

doc1 的 BuyerUserId 将为 6190b06b113314ad2183db09,因为 doc1 的 _id 等于 doc2 的 referenceProductId

我是 mongoDB 的新手,尝试使用以下代码进行更新但不起作用

    { "$match": { "status": "purchased" }},
    {   $lookup:{
            from:"product",
            let:{
               "id":"$Id",
                "referenceProductId":"$ReferenceProductId",
                "userId":"$UserId",
            },
            pipeline:[
                {
                    $match:{
                        $expr:{
                             $eq: ["$$id", "$referenceProductId"] ,
                                
                        }
                    }
                },
            ],
            as:"products"
        }
    },{
        $project:{
             "buyerUserId":"$products.userId"
        }
    }
])

【问题讨论】:

  • 您不能将查找与管道update 一起使用,但您可以使用查找然后$merge 来更新集合。
  • 假设存在匹配项,_id 在给定文档中是否与 referenceProductId 在另一个文档中为 1:1?如果_id 与另一个文档中的referenceProductId 不匹配,会发生什么? buyerUserId 在这种情况下是否未设置?
  • @BuzzMoschetti 是,如果 _id 与另一个文档中的 referenceProductId 不匹配?那么buyerUserId 将被取消设置

标签: node.js database mongodb mongodb-query aggregation-framework


【解决方案1】:

如上面评论中所述,$merge 可用作“文档到文档”更新机制。从 v4.4 开始,您可以将合并的结果直接输出回正在聚合的集合中。

db.foo.aggregate([
    {$lookup: {from: "foo",
               let: {rid: "$_id"},
               pipeline: [
                   {$match:{$expr:{$eq: ["$$rid", "$referenceProductId"]}}}
               ],
               as: "Z"}}

    // If _id->refId match happened, set buyerUserId else do not set
    // anything not even null ($$REMOVE means "do nothing"):
    ,{$project: {buyerUserId: {$cond: [ {$ne:[0,{$size: "$Z"}]}, "$_id", "$$REMOVE"] }} }

    // At this point in pipeline we only have _id and maybe buyerUserId.  Use _id
    // from each doc to merge buyerUserId back into the main collection.
    // Since the docs came from this collection, we should fail if something
    // does not match.
    ,{$merge: {
        into: "foo",
        on: [ "_id" ],
        whenMatched: "merge",
        whenNotMatched: "fail"
    }}

]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-12
    • 2020-04-09
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2018-01-25
    相关资源
    最近更新 更多