Delete an element from an array of an array in MongoDb

耗尽温柔 提交于 2019-12-23 05:37:16

问题


Below is the schema for an array contacts. The contacts array has a field hashtag which is another array. How do I delete an element openLove from the array Hashtags?

"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")
    }

How do I delete an element from the array Hashtags? for example remove openLove?


回答1:


You would normally do this using the positional operator $ as follows:

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

However, as this only supports one-level deep arrays (the positional $ operator acts as a placeholder for the first element that matches the query document), only the first element that matches the query document is removed. There is a JIRA trackable for this here: https://jira.mongodb.org/browse/SERVER-831

If you know the index of the hashtags array that has the elememt to be removed beforehand then the update query will be:

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

Consider redesigning your schema to avoid nested arrays so that you can normalize your collection by creating a separate contacts collection where each document represents a contact, with information common to a set of contacts duplicated in the original collection. Something like the following:

collection schema:

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

contacts schema:

{
    "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")
}

Updating the contacts collection would be easier, simply run the operation

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

If redesigning the schema is out of your scope then you would need a mechanism to dynamically generate the update document i.e. create the $pull object on the fly. Consider using Map-Reduce to generate that, this answer details the whole operation concept.




回答2:


With the help of chridam's answer, I got it to work by using the object Id of each contact.

db.user.update(
{ "contacts._id": ObjectId("5680f392e623e8b2107e6465") },
{
    "$pull": {
        "contacts.$.hashtag": "openLove"
    }
})


来源:https://stackoverflow.com/questions/34507696/delete-an-element-from-an-array-of-an-array-in-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!