How to remove attribute from MongoDb Object? - mongodb

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.

Related

Does MongoDB's $elemMatch projection guarantee the returned element is the same one that was matched in the query?

Let's say I have a collection with this single document:
{
"_id" : ObjectId("…"),
"cartId" : "61",
"items" : [
{
"prodType" : "hardware",
"prod" : "screwdriver",
"checked": false
},
{
"prodType" : "hardware",
"prod" : "hammer",
"checked": false
},
{
"prodType" : "decor",
"prod" : "vase",
"checked": false
}
]
}
And I want to do findAndModify to find any hardware product and modify its checked field. Then it will look like this:
db.col.findAndModify({
query: {
items: {
$elemMatch: {
prodType: "hardware"
}
}
},
update: {
$set: {
"items.$.checked": true
}
}
})
Okay, but this isn't the whole story. findAndModify will return the whole matched document, and I want to project specifically the array item that was matched (and also modified), so I'll add a fields section to my query:
db.col.findAndModify({
query: {
items: {
$elemMatch: {
prodType: "hardware"
}
}
},
update: {
$set: {
"items.$.checked": true
}
},
fields: {
items: {
$elemMatch: {
prodType: "hardware"
}
}
}
})
And now to the question: does MongoDB guarantee that the returned array item from my query is the exact same one that was matched (and modified) in the update section even though we have two items matching the criteria?
YES. It will return only the first sub-document that matched your criteria and was modified in the update section as shown here
According to the official docs, then yes - the projected array element is the exact one that was modified using the same one modified by the positional operator.
$ (update) states:
the positional $ operator acts as a placeholder for the first element that matches the query document
and $elemMatch (projection) states:
The $elemMatch operator limits the contents of an <array> field from the query results to contain only the first element matching the $elemMatch condition
They both apply to the first array element so it directly implies that the modified array element is the one that is projected

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.

MongoDB setOnInsert and push if already existent

I would like to add a document if it does not exist and else add an element to one of it's sub-documents.
db.test.update(
{
name : 'Peter'
},
$setOnInsert : {
name : 'Peter',
visits: { 'en' : ['today'], 'us' : [] }
},
$push : {
visits.en : 'today'
},
{ upsert : true }
)
If Peter exists, add an element to its visists.en or visists.us arrays. Else, create a document for Peter. This document should have the format for visits which should contain the current element ('today').
My issue is that I have "have conflicting mods in update".
I.e. (afaik), I cannot write to two things in one query. Yet how can I solve this dilemma?
You could implement it without $setOnInsert operator.
db.test.update(
{
name : 'Peter'
},
{
$push : {
"visits.en" : 'today'
}
},
{ upsert : true }
)
If Peter exists, element 'today' will be added to its visits.en array. Else, will be created a document for Peter, with visits object, that will be contain array en with 'today' element.
And I think, that error occured because of you using same property (visits) in two operations ($setOnInsert and $push).
You can still use $setOnInsert but when $setOnInsert and $push doesn't updates in the same fields as mentioned before.
N.b: We use $addToSet if you don't want a duplicated values in your Array
db.test.update(
{
name : 'Peter'
},
{
$setOnInsert: {name : 'Peter'},
$addToSet: {"visits.en": 'today'} // or $push
},
{upsert: true})

Mongo DB Delete a field and value

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
);

In Mongodb, how do I push a value into an array?

Let's say my document is this:
{ names: ['jacob','jessie','andrew'] }
I want to push "michael" to all the documents. How do I do that?
db.mycol.update( {}, { $push : { names : "michael" } }, false, true );
Check out the official docs on Updating for more info, the general syntax is:
db.collection.update( criteria, objNew, upsert, multi )
Have you checked this document?
db.your_collection.update({your_documents} { $push : { name : "michel" }})