在Mongodb中使用变更流时,如何过滤更新以不包括父字段

fivyi3re  于 2023-11-17  发布在  Go
关注(0)|答案(1)|浏览(98)

我的文档示例:

{
id: 139234234,
count: 12,
type: apple,
buyer: [
    {name: "peter", price: 1.23, max: 129}, 
    {name: "alex", price: 1.4, "max": 12146}
    ]
}

字符串
我的更新:

db.updateMany({ id: 139234234 }, [
    {
      $set: {
        buyer: {
          $concatArrays: [
            {
              $filter: {
                input: "$buyer",
                cond: {
                    { $ne: ["$$this.name", "john"] },
                },
              },
            },
            [
              {
                name: "john",
                price: 12,
                max: 234,
              },
            ],
          ],
        },
      },
    },
  ]);


我经常在buyer字段中进行这种更新,如果我希望任何更新不包括buyer,我应该为更改流管道(db.collection.watch(changeStreamPipeline))写什么。例如:当前更新描述

updateDescription: {
    updatedFields: {
      'buyer.2.name': "alex",
      'buyer.2.price': 1.4,
      'buyer.2.max': 12146,
      }}


我不想收到任何以buyer开头的updateFields的消息,例如:buyer.2.namebuyer.2.price。我尝试了以下管道,但它只适用于确切为buyer的更新字段:

db.collection.watch(
    [
        {
            $match: {
                operationType: "update",
                "updateDescription.updatedFields.buyer": {
                    $exists: false
                }
            }
        }
    ]
)

13z8s7eq

13z8s7eq1#

你可以做的是在$match阶段之前添加一个$addFields阶段,在这个阶段中,我们将在执行匹配阶段之前从对象中删除所有“buyer”键,以查看是否有任何其他字段被更新,
下面是我如何使用$objectToArray$regexMatch做到这一点:

const pipeline = [
    {
        $addFields: {
            "updateDescription.updatedFields": {
                $arrayToObject: {
                    $filter: {
                        input: {
                            $objectToArray: { $ifNull: ["$updateDescription.updatedFields", {}]}
                        },
                        cond: {
                            $not: { $regexMatch: {input: "$$this.k", regex: /^buyer\..*/,} }
                        }
                    }
                }
            }
        }
    },
    {
        $match: {
            $or: [
                {
                    operationType: {$in: ["update", 'replace']},
                    $expr: {
                        $gt: [
                            {$size: {$objectToArray: { $ifNull: ["$updateDescription.updatedFields", {}]}}},
                            0
                        ]
                    }
                },
                {
                    operationType: {$in: ["delete", 'insert']},
                }
            ]
        }
    }
];

const changeStream = collection.watch(pipeline);

字符串

相关问题