带有一些逻辑的 MongoDB $addToSet

Posted

技术标签:

【中文标题】带有一些逻辑的 MongoDB $addToSet【英文标题】:MongoDB $addToSet wiith some logic 【发布时间】:2020-03-16 12:12:04 【问题描述】:

最终目标是为每个 pathway 对象在 partners 列表中添加一个新合作伙伴(如果它们尚不存在)。如果pathway_name 不等于Engagement Team

例如,我想添加以下合作伙伴:


                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")


 "pathways" : [
        
            "_id" : ObjectId("5d837689b57cc711487f1cf0"), 
            "pathway_name" : "Electronics Technology with Advanced Manufacturing Mechatronics", 
            "partners" : [
                
                    "_id" : ObjectId("5d837ab8b57cc711487f1d28"), 
                    "partner" : ObjectId("5d837426b57cc711487f1c96")
                
            ]
        , 
        
            "_id" : ObjectId("5d837694b57cc711487f1cf1"), 
            "pathway_name" : "Pre-Mechanical Engineering", 
            "partners" : [
                
                    "_id" : ObjectId("5d837acfb57cc711487f1d29"), 
                    "partner" : ObjectId("5d837421b57cc711487f1c92")
                
            ]
        , 
        
            "_id" : ObjectId("5da6055da0eb361cc8da26dc"), 
            "pathway_name" : "Engagement Team", 
            "partners" : [
                
                    "_id" : ObjectId("5da60711a0eb361cc8da26f0"), 
                    "partner" : ObjectId("5d83749fb57cc711487f1cc2")
                
            ]
        
    ], 

我当前的查询如下,我不知道如何添加仅基于 partner 字段本身而不是合作伙伴对象的 _id 字段不存在的合作伙伴的逻辑.

db.getCollection("schools").updateMany(, $addToSet:"pathways$[].partners")

预期结果:

 "pathways" : [
        
            "_id" : ObjectId("5d837689b57cc711487f1cf0"), 
            "pathway_name" : "Electronics Technology with Advanced Manufacturing Mechatronics", 
            "partners" : [
                
                    "_id" : ObjectId("5d837ab8b57cc711487f1d28"), 
                    "partner" : ObjectId("5d837426b57cc711487f1c96")
                ,
                
                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")
                
            ]
        , 
        
            "_id" : ObjectId("5d837694b57cc711487f1cf1"), 
            "pathway_name" : "Pre-Mechanical Engineering", 
            "partners" : [
                
                    "_id" : ObjectId("5d837acfb57cc711487f1d29"), 
                    "partner" : ObjectId("5d837421b57cc711487f1c92")
                ,
                
                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")
                
            ]
        , 
        
            "_id" : ObjectId("5da6055da0eb361cc8da26dc"), 
            "pathway_name" : "Engagement Team", 
            "partners" : [
                
                    "_id" : ObjectId("5da60711a0eb361cc8da26f0"), 
                    "partner" : ObjectId("5d83749fb57cc711487f1cc2")
                
            ]
        
    ], 


【问题讨论】:

它是否有效或仍有问题? 它确实 =],接受。 【参考方案1】:

请尝试并告诉我:

db.getCollection("schools").update(
    ,
    
        $push: 
            'pathways.$[eachPathway].partners': 
                "_id": ObjectId("5dd5762be13e15a73f042ce5"),
                "partner": ObjectId("5dd57633bf0cbbbb36bc112f")
            
        
    ,
     arrayFilters: [ $and: [ "eachPathway.pathway_name":  $ne: "Engagement Team"  ,
    "eachPathway.partners._id":$ne: ObjectId("5dd5762be13e15a73f042ce5")]], multi: true 
)

注意:似乎$addToSet 不适用于整个对象比较,因此我们需要将输入对象中的至少一个字段与数组对象中的相同字段进行比较。 Atlast 我们可以使用$push,因为重复的对象已经被过滤掉了,但是如果您需要整个对象比较,不知道如何实现它 - 我认为它可能不需要。

可能会看到此错误或没有正在更新的文档:

在路径中找不到标识符“eachPathway”的数组过滤器 'pathways.$[eachPathway].partners'

简而言之,这是因为 robo3T 或任何其他正在使用的 mongoDB 客户端无法处理 arrayFilters,因此要测试此查询,请直接测试它使用代码。

参考: No array filter issue

【讨论】:

很抱歉这么晚才接受这个,这有效!我将如何做同样的事情,但生成一个新的_id 字段而不是静态的"_id": ObjectId("5dd5762be13e15a73f042ce5") @Snoopy:你在用猫鼬吗? 是的,我正在使用猫鼬 @Snoopy : 请检查这些并让我知道,如果你有任何问题生成 :: ***.com/questions/17899750/… && ***.com/questions/11604928/… @Snoopy :正如我上面所说的 - 整个对象比较可能不适用于$addToSet,但似乎确实如此,请检查是否有效然后忽略写在上面的检查"eachPathway.partners._id":$ne: ObjectId("5dd5762be13e15a73f042ce5")数组过滤器 :-)

以上是关于带有一些逻辑的 MongoDB $addToSet的主要内容,如果未能解决你的问题,请参考以下文章

在 MongoDb 中使用 addToSet 时保持原始文档的顺序

在对象数组上使用 Mongoose / MongoDB $addToSet 功能

MongoDB聚合,如何在组管道中addToSet数组的每个元素

mongodb 修改操作

如何使用带有 Mongoose 的 addToSet 添加多个 ObjectId?

如何在 Mongoose 中使用 $addToSet 和 ObjectId 数组?