464
{ 
    name: 'book',
    tags: {
        words: ['abc','123'],
        lat: 33,
        long: 22
    }
}

Suppose this is a document. How do I remove "words" completely from all the documents in this collection? I want all documents to be without "words":

 { 
     name: 'book',
     tags: {
         lat: 33,
         long: 22
     }
}
Community
  • 1
  • 1
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

18 Answers18

761

Try this: If your collection was 'example'

db.example.update({}, {$unset: {words:1}}, false, true);

Refer this:

http://www.mongodb.org/display/DOCS/Updating#Updating-%24unset

UPDATE:

The above link no longer covers '$unset'ing. Be sure to add {multi: true} if you want to remove this field from all of the documents in the collection; otherwise, it will only remove it from the first document it finds that matches. See this for updated documentation:

https://docs.mongodb.com/manual/reference/operator/update/unset/

Example:

db.example.update({}, {$unset: {words:1}} , {multi: true});
Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
Shaunak
  • 17,377
  • 5
  • 53
  • 84
  • 1
    See the solution to this question for explanation of false/true http://stackoverflow.com/questions/7714216/add-new-field-to-a-collection-in-mongodb – Dsel Aug 21 '15 at 06:41
  • 1
    There's no longer a comment by a "Nic Cottrell" anywhere on this page :) – Dan Dascalescu Dec 19 '18 at 06:42
  • 21
    Am I missing something, or has this been wrong for 8+ years, because `tags.words` should be `$unset`, not `words`? See also Salvador Dali's answer. – Dan Dascalescu Apr 27 '19 at 04:04
  • 17
    You can also use `updateMany` instead of `{multi:true}`, i.e. `db.example.updateMany({},{"$unset":{words:""}})` – Kip Nov 14 '19 at 15:52
  • Following worked in my case : db.example.update( {}, { $unset: {'column_name':1}}, false, true ) – Dila Gurung May 03 '21 at 04:17
  • 2
    Why do people keep the old code, which does not work, in the updated answer? I assume people come here to look for answers and not scroll down, read complete answer to figured it out the way it was before in 10 years ago. This is very common in SO. – rick Apr 08 '22 at 08:38
  • I did findOneAndUpdate just to get my data as response as : `findOneAndUpdate({ _id: userid },{$unset: {'Details.Expense.2022': 1}})` and my MongoDBCompass shows as an empty object for `Expense` but when I `res.send(result)` it showed an empty array for `2022`, why did that happen ??? – Shubham Singhvi Jun 15 '22 at 06:44
  • The $unset will only unset the property it will not remove it completely. If you console the keys you will still get your unset key as I am getting it. Is there a way to completely remove that property as it was never existed there before. – ARHAM RUMI Apr 26 '23 at 05:43
220

In the beginning, I did not get why the question has a bounty (I thought that the question has a nice answer and there is nothing to add), but then I noticed that the answer which was accepted and upvoted 15 times was actually wrong!

Yes, you have to use $unset operator, but this unset is going to remove the words key which does not exist for a document for a collection. So basically it will do nothing.

So you need to tell Mongo to look in the document tags and then in the words using dot notation. So the correct query is.

db.example.update(
  {},
  { $unset: {'tags.words':1}},
  false, true
)

Just for the sake of completion, I will refer to another way of doing it, which is much worse, but this way you can change the field with any custom code (even based on another field from this document).

Suman Kundu
  • 1,702
  • 15
  • 22
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • 7
    Addition to this, if tags is an array then it would be like this: db.example.update({},{ $unset: {'tags.$[].words':1}},false, true) – Manan Shah Dec 21 '18 at 06:34
73
db.example.updateMany({},{"$unset":{"tags.words":1}})

We can also use this to update multiple documents.

Vipul Pandey
  • 1,507
  • 11
  • 20
  • 9
    i find this clearer than passing `false, true` as last two args to `update()` – Kip Nov 14 '19 at 20:01
26

To remove or delete field in MongoDB

  • For single Record

    db.getCollection('userData').update({}, {$unset: {pi: 1}})
    
  • For Multi Record

    db.getCollection('userData').update({}, {$unset: {pi: 1}}, {multi: true})
    
shA.t
  • 16,580
  • 5
  • 54
  • 111
Viral Patel
  • 921
  • 10
  • 11
26
db.collection.updateMany({}, {$unset: {"fieldName": ""}})

updateMany requires a matching condition for each document, since we are passing {} it is always true. And the second argument uses $unset operator to remove the required field in each document.

Julian Rex
  • 89
  • 1
  • 8
jatinS
  • 566
  • 6
  • 6
18

Starting in Mongo 4.2, it's also possible to use a slightly different syntax:

// { name: "book", tags: { words: ["abc", "123"], lat: 33, long: 22 } }
db.collection.updateMany({}, [{ $unset: ["tags.words"] }])
// { name: "book", tags: { lat: 33, long: 22 } }

Since the update method can accept an aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline), it means the $unset operator used here is the aggregation one (as opposed to the "query" one), whose syntax takes an array of fields.

Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
10

The solution for PyMongo (Python mongo):

db.example.update({}, {'$unset': {'tags.words':1}}, multi=True);
Yakir Tsuberi
  • 1,373
  • 1
  • 12
  • 16
7

To Remove a field you can use this command. Note that with {multi: true} changes will apply to all the documents in the collection:

db.getCollection('example').update({}, {$unset: {Words:1}}, {multi: true});

And to remove multiple fields in one command :

db.getCollection('example').update({}, {$unset: {Words:1 ,Sentences:1}}, {multi: true});
Kaveh Naseri
  • 1,102
  • 2
  • 15
  • 24
4

I was trying to do something similar to this but instead remove the column from an embedded document. It took me a while to find a solution and this was the first post I came across so I thought I would post this here for anyone else trying to do the same.

So lets say instead your data looks like this:

{ 
  name: 'book',
  tags: [
    {
      words: ['abc','123'],
      lat: 33,
      long: 22
    }, {
      words: ['def','456'],
      lat: 44,
      long: 33
    }
  ]
}

To remove the column words from the embedded document, do this:

db.example.update(
  {'tags': {'$exists': true}},
  { $unset: {'tags.$[].words': 1}},
  {multi: true}
)

or using the updateMany

db.example.updateMany(
  {'tags': {'$exists': true}},
  { $unset: {'tags.$[].words': 1}}
)

The $unset will only edit it if the value exists but it will not do a safe navigation (it wont check if tags exists first) so the exists is needed on the embedded document.

This uses the all positional operator ($[]) which was introduced in version 3.6

Jonathon Gardner
  • 473
  • 6
  • 12
  • This answer needs to be upvoted more, but I guess it's difficult to compete with answers that are 6 years older. – HeatZync May 30 '22 at 08:40
3

Because I kept finding this page when looking for a way to remove a field using MongoEngine, I guess it might be helpful to post the MongoEngine way here too:

Example.objects.all().update(unset__tags__words=1)
Mathieu Dhondt
  • 8,405
  • 5
  • 37
  • 58
3

In mongoDB shell this code might be helpful:

db.collection.update({}, {$unset: {fieldname: ""}} )
Vince
  • 776
  • 11
  • 21
2

By default, the update() method updates a single document. Set the Multi Parameter to update all documents that match the query criteria.

Changed in version 3.6. Syntax :

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

Example :

db.getCollection('products').update({},{$unset: {translate:1, qordoba_translation_version:1}}, {multi: true})

In your example :

db.getCollection('products').update({},{$unset: {'tags.words' :1}},  {multi: true})
Amitesh Bharti
  • 14,264
  • 6
  • 62
  • 62
2

And for mongomapper,

  • Document: Shutoff
  • Field to remove: shutoff_type

Shutoff.collection.update( {}, { '$unset' => { 'shutoff_type': 1 } }, :multi => true )

Jon Kern
  • 3,186
  • 32
  • 34
0

It's worth mentioning, if you are using Typegoose/Mongoose your field needs to be declared in your model otherwise $unset will silently fail.

After a refactoring of a database this caught me unaware. The redundant fields were no longer in my model and I was running an $unset but nothing was happening.

So if you are doing some refactoring make sure you $unset your redundant fields before removing them from the model.

joe92
  • 635
  • 2
  • 11
  • 19
-2

{ name: 'book', tags: { words: ['abc','123'], lat: 33, long: 22 } }

Ans:

db.tablename.remove({'tags.words':['abc','123']})

-3

Checking if "words" exists and then removing from the document

    db.users.update({"tags.words" :{$exists: true}},
                                           {$unset:{"tags.words":1}},false,true);

true indicates update multiple documents if matched.

Abhi
  • 6,471
  • 6
  • 40
  • 57
  • You don't need to check for existence. The [documentation states](https://docs.mongodb.com/manual/reference/operator/update/unset/#behavior) that :"If the field does not exist, then $unset does nothing (i.e. no operation)." – Dan Dascalescu Sep 28 '18 at 09:58
-4

you can also do this in aggregation by using project at 3.4

{$project: {"tags.words": 0} }

joel Raja
  • 59
  • 5
-7

To reference a package and remove various "keys", try this

db['name1.name2.name3.Properties'].remove([
{
     "key" : "name_key1"
},
{
     "key" : "name_key2"
},
{
     "key" : "name_key3"
}
)]
taskinoor
  • 45,586
  • 12
  • 116
  • 142
aspadacio
  • 323
  • 2
  • 12