Mongo DB Delete a field and value - mongodb

In mongo shell how would I delete all occurrences of "id" : "1" the value of the field is always different. Would I use the $unset operator? Would that delete the value and the field?

You're saying remove all occurrences of the field, right? If so, then it should be like this:
db.collection.update(
{ id: { $exists: true } }, // criteria
{ $unset: { id: 1 } }, // modifier
false, // no need to upsert
true // multi-update
);

Related

mongodb - how to insert a new key/value on each array's element if not present (with mongo query)

I would like to update each elements (object) in an array of a company.
Here my actual data :
{
_id: ObjectId("60d31024860ce0400b586111")
contracts:
[
{
name: 1.pdf
url: "https://someurl"
createdAt: 2021-06-23T10:42:44.594+00:00
}
{
name: 2.pdf
url: "https://someurl"
}
{
name: 3.pdf
url: "https://someurl"
}
]
}
I would like to add a defined date on each object (in contracts) that has no "updatedAt" key.
Here what I tried :
db.companies.update({ _id: ObjectId("60d31024860ce0400b586111"),"contracts.createdAt": { $exists: false } },{ $set: { "contracts.$.createdAt": "test" } })
but I got this error :
"The positional operator did not find the match needed from the query."
I have also tried this and it works, but I don't wanna query by file name. I just wanna add "createdAt" on each elements found that has no "createdAt"
db.companies.update({ "contracts.name": "2.pdf" },{ $set: { "contracts.$.createdAt": "atest" } })
I think you need to use the filtered position operator:
$ - updates the first matched array element
$[] - updates all the matched elements with a specific condition
The specific condition is mentioned in the arrayFilters key.
db.students.update(
{ },
{ $set: { "contracts.$[element].createdAt" : "atest"} },
{ multi: true,
arrayFilters: [ { "element.createdAt": { $exists: false } } ]
}
)
multi - true is to apply the operation on all the matching documents.
Also notice, how the first query parameter is empty, which means the query runs for all documents. I used it based on the second query you wrote but you can also add in an ObjectID query there.

How easy rename keys in mongodb arrays?

I have collection where documents have field as an array. I need to rename one field inside each item of this array, but in mongodb all variants looks very monstrous. I even try to use $[] but I can't refer to old value of object, only custom:
collection.update(
{ customField: { $exists: true } },
{
$set:
{
'payload.oneMoreField.$[].path': 'howReferToOldValue',
},
$unset:
{
'payload.oneMoreField.$[].way': '',
},
},
options
);
Somebody knows an easy way to just change the value of a key in monogodb ?

Updating the path 'x' would create a conflict at 'x'

This error happens when I tried to update upsert item:
Updating the path 'x' would create a conflict at 'x'
Field should appear either in $set, or in $setOnInsert. Not in both.
I had the same problem while performing an update query using PyMongo.
I was trying to do:
> db.people.update( {'name':'lmn'}, { $inc : { 'key1' : 2 }, $set: { 'key1' : 5 }})
Notice that here I'm trying to update the value of key1 from two MongoDB Update Operators.
This basically happens when you try to update the value of a same key with more than one MongoDB Update Operators within the same query.
You can find a list of Update Operators over here
If you pass the same key in $set and in $unset when updating an item, you will get that error.
For example:
const body = {
_id: '47b82d36f33ad21b90'
name: 'John',
lastName: 'Smith'
}
MyModel.findByIdAndUpdate(body._id, { $set: body, $unset: {name: 1}})
// Updating the path 'name' would create a conflict at 'name'
You cannot have the same path referenced more than once in an update. For example, even though the below would result in something logical, MongoDB will not allow it.
db.getCollection("user").updateOne(
{_id: ...},
{$set: {'address': {state: 'CA'}, 'address.city' : 'San Diego'}}
)
You would get the following error:
Updating the path 'address.city' would create a conflict at 'address'
db.products.update(
{ _id: 1 },
{
$set: { item: "apple" },
$setOnInsert: { defaultQty: 100 }
},
{ upsert: true }
)
Below is the key explanation to the issue:
MongoDB creates a new document with _id equal to 1 from the
condition, and then applies the $set AND $setOnInsert operations to
this document.
If you want a field value is set or updated regardless of insertion or update, use it in $set. If you want it to be set only on insertion, use it in $setOnInsert.
Here is the example: https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/#example
Starting from MongoDB 4.2 you can use aggregate pipelines in update:
db.your_collection.update({
_id: 1
},
[{
$set:{
x_field: {
$cond: {
if: {$eq:[{$type:"$_id"} , "missing"]},
then: 'upsert value', // it's the upsert case
else: '$x_field' // it's the update case
}
}
}
}],
{
upsert: true
})
db.collection.bulkWrite() also supports it
With the Ruby library at least, it's possible to get this error if you have the same key twice, once as a symbol and once as a string:
db.getCollection("user").updateOne(
{_id: ...},
{$set: {'name': "Horse", name: "Horse"}}
)
I recently had the same issue while using the query below.
TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.note': req.body.note } }, { upsert: true, new: true })
When i have changed 'content.note' to 'content.$.note' it has been fixed. So my final query is :
TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.$.note': req.body.note } }, { upsert: true, new: true })

How does $unset work?

In the mongo documentation unsetting a field is done with $unset. I can't quite grasp how it works, but it seems like it should be simple.
The following operation uses the $unset operator to remove the tags field:
db.books.update( { _id: 1 }, { $unset: { tags: 1 } } )
My confusion arises when setting what to unset. What is the value 1 for in the $unset clause?
As per the $unset documentation :-
The $unset operator deletes a particular field.
Syntax : { $unset: { <field1>: "", ... } }
The specified value in the $unset expression (i.e. "") does not impact the operation.
If the field does not exist, then $unset does nothing (i.e. no operation).
So you can use
db.books.update( { _id: 1 }, { $unset: { tags: 1 } } )
OR
db.books.update( { _id: 1 }, { $unset: { tags: 0 } } )
OR
db.books.update( { _id: 1 }, { $unset: { tags: "" } } )
All the above queries will delete tags field.
Hope your doubt is clear now.
{$unset : { tags : 1 } } will clear the field tags from the document. The value 1 is just to tell that, clear this field tags from the document.
If you want to clear multiple fields, you need to write {$unset : { tags : 1, randomField : 1} } and like that.
You can refer official documentation of $unset for further info.
According to the documentation:
The $unset operator deletes a particular field. Consider the
following syntax:
{ $unset: { field1: "", ... } }
The specified value in the $unset
expression (i.e. "") does not impact the operation.
If the field does not exist, then $unset does nothing (i.e. no
operation).
When used with $ to match an array element, $unset replaces the
matching element with null rather than removing the matching element
from the array.
The $unset operator deletes a particular field.

How to remove attribute from MongoDb Object?

I have added MiddleName attribute to my Customer object. Customer is a simple Object() instance. I want to remove this attribute from my object. How can I do that? I am using MongoDb interactive Console.
You should use the $unset modifier while updating:
To delete: (most recent syntax)
https://docs.mongodb.com/manual/reference/method/db.collection.update/
db.collection.update(
{},
{
$unset : {
"properties.service" : 1
}
},
{
multi: true
}
);
Updated thanks to Xavier Guihot comment!
To delete: (only left for reference of the old syntax)
// db.collection.update( criteria, objNew, upsert, multi )
db.collection.update(
{
"properties.service" : {
$exists : true
}
},
{
$unset : {
"properties.service" : 1
}
},
false,
true
);
To verify they have been deleted you can use:
db.collection.find(
{
"properties.service" : {
$exists : true
}
}
).count(true);
Remember to use the multi option as true if you want to update multiple records.
In my case I wanted to delete the properties.service attribute from all records on this collection.