How to remove array element in mongodb?
Asked Answered
T

6

223

Here is array structure

contact: {
    phone: [
        {
            number: "+1786543589455",
            place: "New Jersey",
            createdAt: ""
        }
        {
            number: "+1986543589455",
            place: "Houston",
            createdAt: ""
        }

    ]
}

Here I only know the mongo id(_id) and phone number(+1786543589455) and I need to remove that whole corresponding array element from document. i.e zero indexed element in phone array is matched with phone number and need to remove the corresponding array element.

contact: {
    phone: [
        {
            number: "+1986543589455",
            place: "Houston",
            createdAt: ""
        }
    ]
}

I tried with following update method

collection.update(
    { _id: id, 'contact.phone': '+1786543589455' },
    { $unset: { 'contact.phone.$.number': '+1786543589455'} }
);

But it removes number: +1786543589455 from inner array object, not zero indexed element in phone array. Tried with pull also without a success.

How to remove the array element in mongodb?

Teressaterete answered 6/6, 2013 at 9:58 Comment(0)
S
366

Try the following query:

collection.update(
  { _id: id },
  { $pull: { 'contact.phone': { number: '+1786543589455' } } }
);

It will find document with the given _id and remove the phone +1786543589455 from its contact.phone array.

You can use $unset to unset the value in the array (set it to null), but not to remove it completely.

Supercharger answered 6/6, 2013 at 10:25 Comment(5)
Thank you. It works nice. I tried with { $pull: { 'contact.phone.$': { 'contact.phone.$.number': '+1786543589455' } } } and { $pull: { 'contact.phone': { 'contact.phone.$.number': '+1786543589455' } } } without a success. Doesn't understand working of positional operators here?Teressaterete
Is there call back with this?Protestant
@iLoveUnicorns you could add a callback as a third argument, or you could use returned promise.Supercharger
@LeonidBeschastny I tried this. In my case, I've multiple documents with same key. I want to $pull all these documents but current query only changes 1 document and then stops. What changes I need?Gin
@ShubhamA. by default .update() updates a single document. To update multiple documents use { multi: true } option. See db.collection.update docs for details.Supercharger
F
8

You can simply use $pull to remove a sub-document. The $pull operator removes from an existing array all instances of a value or values that match a specified condition.

Collection.update({
    _id: parentDocumentId
  }, {
    $pull: {
      subDocument: {
        _id: SubDocumentId
      }
    }
  });

This will find your parent document against given ID and then will remove the element from subDocument which matched the given criteria.

Read more about pull here.

Froufrou answered 23/8, 2018 at 9:18 Comment(0)
G
6

In Mongoose: from the document:

To remove a document from a subdocument array we may pass an object with a matching _id.

contact.phone.pull({ _id: itemId }) // remove
contact.phone.pull(itemId); // this also works

See Leonid Beschastny's answer for the correct answer.

Giacobo answered 10/4, 2019 at 8:38 Comment(0)
I
4

To remove all matching array elements from a specific document:

collection.update(
  { _id: id },
  { $pull: { 'contact.phone': { number: '+1786543589455' } } }
);

To remove all matching array elements from all documents:

collection.updateMany(
  { },
  { $pull: { 'contact.phone': { number: '+1786543589455' } } }
);
Inanity answered 9/9, 2022 at 19:21 Comment(0)
C
3

To remove all array elements irrespective of any given id, use this:

collection.update(
  { },
  { $pull: { 'contact.phone': { number: '+1786543589455' } } }
);
Crossbar answered 10/10, 2020 at 14:57 Comment(0)
M
3

Given the following document in the profiles collection:

{ 
   _id: 1, 
   votes: [ 3, 5, 6, 7, 7, 8 ] 
}

The following operation will remove all items from the votes array that are greater than or equal to ($gte) 6:

db.profiles.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )

After the update operation, the document only has values less than 6:

{ 
   _id: 1, 
   votes: [  3,  5 ] 
}

If you have multiple items the with the same value, you should use $pullAll instead of $pull.

In the question having a multiple contact numbers the same use this:

collection.update(
  { _id: id },
  { $pullAll: { 'contact.phone': { number: '+1786543589455' } } }
);

It will delete every item that matches that number in contact phone.

Try reading the manual.

Mulciber answered 8/12, 2021 at 4:36 Comment(1)
In the question having a fax number and a voice number the sameuseMulciber

© 2022 - 2024 — McMap. All rights reserved.