I have thousands of documents in this format:
{
"_id" : ObjectId("51e98d196b01c2085c72d731"),
"messages" : [
{
"_id" : ObjectId("520167056b01c20bb9eee987"),
"id" : ObjectId("520167056b01c20bb9eee987"),
},
{
"_id" : ObjectId("520167056b01c20bb9eee988"),
"id" : ObjectId("520167056b01c20bb9eee988"),
},
{
"_id" : ObjectId("520167056b01c20bb9eee989"),
"id" : ObjectId("520167056b01c20bb9eee989"),
}
],
}
I need to remove the duplicate "id" field. This is what I have tried:
db.forum_threads.update({}, {$unset: {"messages.$.id": 1}}, {multi: true});
This is the error I am getting:
Cannot apply the positional operator without a corresponding query field containing an array.
To remove an element, update, and use $pull in MongoDB. The $pull operator removes from an existing array all instances of a value or values that match a specified condition.
To remove an element from a doubly-nested array in MongoDB document, you can use $pull operator. Now field "UserZipCode": "20010" has been removed from a doubly-nested array.
You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.
How to remove a field completely from a MongoDB document? You can use $unset operator to remove a field completely from a MongoDb document. The syntax is as follows:
Actually it will remove the value, BUT only from the first occurrence of the subdocument, because of the way positional operator works: You also can not use $unset (as you tried before) because it can not work on arrays (and are you basically trying to remove a key from a document from the array).
Also, to count the longest array in a mongodb object, an aggregate can be done, something like this: Just want to emphasize that this is not a pretty solution but is way faster than fetching and saving. Not the answer you're looking for?
The reason you're getting that error is because you don't have any predicate in the filter clause. You can do this:
mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true})
And you won't get an error - in fact one of the documents will have the id
attribute removed. The problem is that the positional operator only matches the FIRST element of the array that matches your predicate, it doesn't match all elements. The bigger issue is that it's not currently possible to update all the elements in an array in MongoDB (https://jira.mongodb.org/browse/SERVER-1243).
You'll either need to iterate through each element in the array using the numerical position ("messages.0.id", "messages.1.id", etc.) or you can pull the array into your application, loop through the elements and update them, and then save the array back out.
You can see from the JIRA ticket that this issue has been open for quite awhile but 10gen doesn't seem to consider it very high priority.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With