从MongoDb中数组的数组中删除一个元素

Posted

技术标签:

【中文标题】从MongoDb中数组的数组中删除一个元素【英文标题】:Delete an element from an array of an array in MongoDb 【发布时间】:2016-04-03 03:20:57 【问题描述】:

以下是数组联系人的架构。联系人数组有一个字段标签,它是另一个数组。如何从数组 Hashtags 中删除元素 openLove?

"contacts" : [
    
        "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
        "personEmailId" : "tell.fadgfdg@gmail.com",
        "_id" : ObjectId("565eb481bf35eeb83d7f9f13"),
        "verified" : true,
        "favorite" : true,
        "linkedinUserName" : null,
        "facebookUserName" : null,
        "twitterUserName" : "IamlifePaul",
        "count" : 2,
        "relationshipStrength_updated" : 0,
        "contactRelation" : 
            "decisionmaker_influencer" : null,
            "prospect_customer" : "prospect"
        ,
        "source" : "abc",
        "mobileNumber" : "3546789",
        "skypeId" : "123",
        "designation" : "test",
        "companyName" : "Something",
        "location" : "Hyderabad, Telangana, India",
        "personName" : "Naveen Paul",
        "personId" : "565022d7dbeaeb9e17fc7083",
        "hashtag" : [

            "latestTag",
            "anotherTag",
            "#hash",
            "openLove",
            "hellTwo",
            "working?",
            "hello",
            "lol",
            "zxc"
        ],
        "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")
    ,

        "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
        "personEmailId" : "naveenpaul.fadgfdg@gmail.com",
        "_id" : ObjectId("565eb481bf35eeb83d7f9f13"),
        "verified" : true,
        "favorite" : true,
        "linkedinUserName" : null,
        "facebookUserName" : null,
        "twitterUserName" : "IamlifePaul",
        "count" : 2,
        "relationshipStrength_updated" : 0,
        "contactRelation" : 
            "decisionmaker_influencer" : null,
            "prospect_customer" : "prospect"
        ,
        "source" : "abc",
        "mobileNumber" : "3546789",
        "skypeId" : "123",
        "designation" : "test",
        "companyName" : "Something",
        "location" : "Hyderabad, Telangana, India",
        "personName" : "Naveen Paul",
        "personId" : "565022d7dbeaeb9e17fc7083",
        "hashtag" : [

            "latestTag",
            "anotherTag",
            "#hash",
            "openLove",
            "hellTwo",
            "working?",
            "hello",
            "lol",
            "zxc"
        ],
        "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")
    ,

        "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
        "personEmailId" : "naveenpaul.fadgfdg@gmail.com",
        "_id" : ObjectId("565eb481bf35eeb83d7f9f13"),
        "verified" : true,
        "favorite" : true,
        "linkedinUserName" : null,
        "facebookUserName" : null,
        "twitterUserName" : "IamlifePaul",
        "count" : 2,
        "relationshipStrength_updated" : 0,
        "contactRelation" : 
            "decisionmaker_influencer" : null,
            "prospect_customer" : "prospect"
        ,
        "source" : "abc",
        "mobileNumber" : "3546789",
        "skypeId" : "123",
        "designation" : "test",
        "companyName" : "Something",
        "location" : "Hyderabad, Telangana, India",
        "personName" : "Naveen Paul",
        "personId" : "565022d7dbeaeb9e17fc7083",
        "hashtag" : [

            "polly",
            "tagger",
            "#hash",
            "working?",
            "hello",
            "lol",
            "zxc"
        ],
        "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")
    

如何从 Hashtags 数组中删除元素? 例如删除 openLove?

【问题讨论】:

How to remove an element from a doubly-nested array in a MongoDB document的可能重复 【参考方案1】:

您通常会使用 positional operator $ 执行此操作,如下所示:

db.collection.update(
     "contacts.hashtag": "openLove" ,
    
        "$pull": 
            "contacts.$.hashtag": "openLove"
        
    
)

但是,由于这仅支持单级深度数组(位置 $ operator 充当与查询文档匹配的第一个元素的占位符),因此仅支持与查询匹配的第一个元素文档被删除。这里有一个可跟踪的 JIRA:https://jira.mongodb.org/browse/SERVER-831

如果您事先知道要删除元素的主题标签数组的索引,则更新查询将是:

db.collection.update(
     "contacts.hashtag": "openLove" ,
    
        "$pull": 
            "contacts.0.hashtag": "openLove",
            "contacts.1.hashtag": "openLove"
        
    
)

考虑重新设计您的架构以避免嵌套数组,以便您可以通过创建一个单独的联系人集合来规范您的集合,其中每个文档代表一个联系人,其中包含原始集合中重复的一组联系人的通用信息。类似于以下内容:

集合架构:


    _id: collection_id,
    contacts: [
        ObjectId("565eb481bf35eeb83d7f9f13"), 
        ObjectId("565eb481bf35eeb83d7f9f14"), 
        ObjectId("565eb481bf35eeb83d7f9f15")
    ]

联系人架构:


    "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
    "personEmailId" : "tell.fadgfdg@gmail.com",
    "_id" : ObjectId("565eb481bf35eeb83d7f9f13"),
    ...
    "hashtag" : [
        "latestTag",
        "anotherTag",
        "#hash",
        "openLove",
        "hellTwo",
        "working?",
        "hello",
        "lol",
        "zxc"
    ],
    "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")
,

    "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
    "personEmailId" : "naveenpaul.fadgfdg@gmail.com",
    "_id" : ObjectId("565eb481bf35eeb83d7f9f14"),
    ...
    "hashtag" : [
        "latestTag",
        "anotherTag",
        "#hash",
        "openLove",
        "hellTwo",
        "working?",
        "hello",
        "lol",
        "zxc"
    ],
    "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")
,

    "addedDate" : ISODate("2015-12-02T09:06:09.891Z"),
    "personEmailId" : "naveenpaul.eewsdf@gmail.com",
    "_id" : ObjectId("565eb481bf35eeb83d7f9f15"),
    ...
    "hashtag" : [
        "polly",
        "tagger",
        "#hash",
        "working?",
        "hello",
        "lol",
        "zxc"
    ],
    "lastInteracted" : ISODate("2015-12-08T05:07:53.746Z")

更新联系人集合会更容易,只需运行操作

db.contacts.update(
     "hashtag": "openLove" ,
    
        "$pull":  "hashtag": "openLove" 
    
)

如果重新设计架构超出了您的范围,那么您将需要一种机制来动态生成更新文档,即动态创建 $pull 对象。考虑使用 Map-Reduce 来生成它,这个 answer 详细说明了整个操作概念。

【讨论】:

【参考方案2】:

在chridam's 回答的帮助下,我通过使用每个联系人的对象 ID 让它工作。

db.user.update(
 "contacts._id": ObjectId("5680f392e623e8b2107e6465") ,

    "$pull": 
        "contacts.$.hashtag": "openLove"
    
)

【讨论】:

以上是关于从MongoDb中数组的数组中删除一个元素的主要内容,如果未能解决你的问题,请参考以下文章

从嵌套数组mongodb中删除元素

MongoDB:从数组的开头删除一定数量的元素

从 mongodb 数组中的所有重复项中拉出一个元素

如何从js中的数组中删除元素[元素来自mongodb] [重复]

如何从js中的数组中删除元素[元素来自mongodb] [重复]

如何从 MongoDB 文档中的双重嵌套数组中删除元素。