首页 > 解决方案 > MongoDB 推送用户在 mongodb 对象数组中提供的对象数组,这样不会有任何重复

问题描述

假设我有一个文档集合

{ "id":1, "arr":[{"a":1, "b":2, "c":3}, {"a":6, "b":0, "c":8},....]}
{ "id":2, "arr":[{"a":7, "b":1, "c":4}, {"a":5, "b":2, "c":6},....]}

现在用户将为我提供一个像这样的未知大小的数组

let user_id: 2;
let user_arr = [{"a":7, "b":1, "c":9}, {"a":1, "b":6, "c":3},.....]

现在我想将用户提供的 arr 文档推送到用户arruser_id定的用户中,这样(a,b)两个值的组合就不会为他/她重复。

例如 - 对于上面(a:7, b:1)已经存在的情况,arr所以它不会被插入,但是(a:1, b:6)没有记录包含它们,这就是它{"a":1, "b":6, "c":3}被插入到 arr 中的原因。

请帮助我,任何人。

标签: mongodbaggregation-framework

解决方案


您可以结合使用$elemMatch$not来检查您尝试$push的文档是否不会复制该数组中的任何其他子文档。尝试:

db.col.update({ id: user_id, arr: { $not: { $elemMatch: { a: 7, b: 1 } } } }, { $push: { arr: { a:7, b:1, c:9} } })

附加条件id将强制此操作修改一个或零个文档。

要执行多个更新,您可以使用bulkWrite (MongoDB 3.2+):

db.col.bulkWrite(
    [
        { 
            updateOne : {
                    "filter" : { id: 2, arr: { $not: { $elemMatch: { a: 7, b: 1 } } } },
                    "update" : { $push: { arr: { a:7, b:1, c:9} } }
                }
        },
        { 
            updateOne : {
                    "filter" : { id: 2, arr: { $not: { $elemMatch: { a: 1, b: 6 } } } },
                    "update" : { $push: { arr: { a:1, b:6, c:3} } }
                }
        }
    ]
);

作为回应,您将得到:

{
    "acknowledged" : true,
    "deletedCount" : 0,
    "insertedCount" : 0,
    "matchedCount" : 1,
    "upsertedCount" : 0,
    "insertedIds" : {

    },
    "upsertedIds" : {

    }
}

这意味着只有两个条件之一与文档匹配id2


推荐阅读