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

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" }})

Related

Mongodb- Query to check if a field in the json array exists or not

I have a JSON in MongoDB and I am trying to check if at least one of the items in the JSON doesn't contain a specific field.
{
"_id" : 12345,
"orderItems" : [
{
"itemId" : 45678,
"isAvailable" : true,
"isEligible" " false
},
{
"itemId" : 87653,
"isAvailable" : true
}
]
}
So in the above JSON, since the 2nd one under order items doesn't contain iseligible field, I need to get this _id.
I tried the below query so far, which didnt work:
db.getCollection('orders').find({"orderItems.iseligible":{$exists:false})
You can use $elemMatch to evaluate the presence of the nested key. Once that's accomplished, project out the _id value.
db.orders.find({
orderItems: {
$elemMatch: {
"isEligible": {
$exists: false
}
}
}
},
{
_id: 1
})
Here is a Mongo playground with the finished code, and a similar SO answer.

update nested object in MongoDB

I'm new in MongoDB.I have read almost all relative posts but cannot find a proper answer for my case. Suppose you have the document:
{ "_id" : "5ad1..",
"linkedin" : { "linkedinId" : "NB..J", "username" : "dolguldur",
"followers":[{name:"John",email:"john#example.com},{name:"Elsa",email:"elsa#example.com}]
}
}
If a follower changes his email, how can i update his record with the new one;
Use the $elemMatch operator to select your desired nested object :
db.collection.update({
followers: {
$elemMatch: {
name: _follower_name,
email: _follower_email
}
}
}, {
"followers.$.email": new_mail
});
The $ positional operator will select the first nested object that match the filter in $elemMatch and update it.

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

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

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.