I want add new data my nested array
My document is:
{
"username": "erkin",
"email": "erkin-07#hotmail.com",
"password": "b",
"playlists": [
{
"_id": 58,
"name": "asdsa",
"date": "09-01-15",
"musics": [
{
"name": "INNA - Cola Song (feat. J Balvin)",
"duration": "3.00"
},
{
"name": "blabla",
"duration": "3.00"
}
]
}
]
}
I want add music in this playlist section:
{
"username": "erkin",
"email": "erkin-07#hotmail.com",
"password": "b",
"playlists": [
{
"_id": 58,
"name": "asdsa",
"date": "09-01-15",
"musics": [
{
"name": "INNA - Cola Song (feat. J Balvin)",
"duration": "3.00"
},
{
"name": "blabla",
"duration": "3.00"
},
{
"name": "new",
"duration": "3.00"
}
]
}
]
}
Here is what I tried:
$users->update(
array(
'_id' => new MongoId (Session::get('id')),
'playlists._id' => $playlistId
),
array(
'$push' => array('playlists.musics' => array(
'name' => 'newrecord',
'duration' => '3.00'
))
)
);
Probably something like this where ID is your ObjectId. The first {} are necessary to identify your document. It is not required to use an ObjectId as long as you have another unique identifier in your collection.
db.collection.update(
{ "_id": ID, "playlists._id": "58"},
{ "$push":
{"playlists.$.musics":
{
"name": "test name",
"duration": "4.00"
}
}
}
)
This way it worked for me!
"playlists.$[].musics":
db.collection.update(
{ "_id": ID, "playlists._id": "58"},
{ "$push":
{"playlists.$[].musics":
{
"name": "test name",
"duration": "4.00"
}
}
}
)
https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#position-nested-arrays-filtered
I suggest you using arrayFilters since it supports multiple nested documents and clearer.
db.collection.update(
{ "_id": ID},
{ "$push":
{"playlists.$[i].musics":
{
"name": "test name",
"duration": "4.00"
}
}
},
{
arrayFilters: [
{'i._id': 58,},
],
},
)
2022 update:
Full snippet:
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/', maxPoolSize=50)
db = client.name_of_db
collection = db["name_of_collection"]
To push:
collection.find_one_and_update(
{"_id": 'id_of_the_document'},
{"$push": {"key":"value"}})
To push into nested:
collection.find_one_and_update(
{"_id": 'id_of_the_document'},
{"$push": {"key.nested_key":"value"}})
Related
There is a sub-field called 'name' in MongoDB Collection (User):
[
{
"teacher": {
"name": "Alex",
"email": "alex#domain.com"
},
"waiter": {
"name": "Feliks",
"email": "feliks#domain.com"
},
"pilot": [
{
"name": "Sam",
"email": "sam#domain.com"
},
{
"name": "alice",
"email": "alice#domain.com"
}
],
},
{
"teacher": {
"name": "max",
"email": "max#domain.com"
},
"waiter": {
"name": "Sam",
"email": "sam#domain.com"
},
"pilot": [
{
"name": "richard",
"email": "richard#domain.com"
},
{
"name": "alice",
"email": "alice#domain.com"
}
],
}
]
How can I find data based on the field 'name'. For example, when I'm looking for 'Sam', it should return me the all documents since 'Sam' is in "waiter" and "pilot" in first and second documents respectively.
I cannot do something like:
User.find({"teacher.name": "Sam", "waiter.name": "Sam", "pilot.name": "Sam" })
This will return me nothing as it is an AND logic. What I need is an OR logic.
You can use the $or operator.
So the query should look like this:
User.find({ $or: [
{ "teacher.name": "Sam" },
{ "waiter.name": "Sam" },
{ "pilot.name": "Sam" }
]
});
Read here for me details.
I have an array of values to update with existing array. I tried with $set it throws a error. If I have an array of values to update it should update matching item in the array.
1.If I have following documents in a collection
table
[
{
"id": 1,
"name": "Fresh Mart",
"products": [
{
"name": "Onion",
"qty": 10,
"price": "85"
},
{
"name": "Tomato",
"qty": 10,
"price": "85"
}
]
},
{
"id": 2,
"name": "Alfred super market",
"products": [
{
"name": "Onion",
"qty": 10,
"price": "85"
},
{
"name": "Tomato",
"qty": 10,
"price": "85"
}
]
}
]
Following query updates one product in first document:
Query
db.collection.update({
"$and": [
{
id: 1
},
{
"products.name": "Onion"
}
]
},
{
"$set": {
"products.name": "Onion Updated"
}
})
I tried to update both products in the first document with following query:
db.collection.update({
"$and": [
{
id: 1
},
{
"products.name": [ "Onion", "Tomato" ]
}
]
},
{
"$set": {
"products.name": "Onion Updated"
}
})
db.collection.update({
id: 1
},
{
"$addToSet": {
"products": {
"$each": [
{
"name": "Onion Updated",
"qty": 10,
"price": "85"
},
{
"name": "Tomato Updated",
"qty": 10,
"price": "85"
}
]
}
}
})
I used $addToSet it will not allow the duplicates. Is possible to replace existing value with $addToSet
but it didn't update the document.
This answer is the dynamic approach of this answer https://stackoverflow.com/a/49870042/8987128
Configure your payload
let id = 1;
let updateName = [
{
oldName: "Onion",
newName: "Onion Updated"
},
{
oldName: "Tomato",
newName: "Tomato Updated"
},
];
Prepare arrayFilters and set conditions
let arrayFilters = [];
let set = {};
updateName.forEach((v, i) => {
arrayFilters.push({ ["p"+i]: v.oldName });
set["products.$[p"+i+"].name"] = v.newName;
});
Update query
db.collection.update(
{ id: id },
{ $set: set },
{ arrayFilters: arrayFilters }
)
Playground
I used node mongoose.
I need to update this array push new item into Breackfast(mealList.foodList.breackfast || any),
I want to add new foodlist by time can you please give me suggestion for how to do,
{
"_id": "5fe43eb44cd6820963c98c32",
"name": "Monday Diet",
"userID": "5f225d7458b48d0fe897662e",
"day": "Monday",
"type": "private",
"mealList": [
{
"_id": "5fe43eb44cd6820963c98c33",
"time": "Breakfast",
"foodList": [
{
"_id": "5fe43eb44cd6820963c98c34",
"foodName": "Eggs",
"Qty": "2",
"calories": "calories",
"category": "category"
}
]
},
{
"_id": "5fe43eb44cd6820963c98c36",
"time": "Lunch",
"foodList": [
{
"_id": "5fe43eb44cd6820963c98c37",
"foodName": "food1",
"Qty": "100g"
},
]
}
],
"createdAt": "2020-12-24T07:09:40.141Z",
"updatedAt": "2020-12-24T07:09:40.141Z",
"__v": 0
}
I tried:
Diet.updateOne(
{ "Diet.mealList._id": req.body.mealId },
// { $push: { "Diet.0.mealList.$.foodList": req.body.foodList } },
{ $push: { foodList: req.body.foodList } }
)
Few Fixes:
convert your string _id to object type using mongoose.Types.ObjectId
remove Diet from first and push object in foodList
Diet.updateOne({
"mealList._id": mongoose.Types.ObjectId(req.body.mealId)
},
{
$push: {
"mealList.$.foodList": req.body.foodList
}
})
Playground
Here is my mongo schema:
{
"_id": ObjectId("5f8af2fc5f23667adf3bbaf2"),
"score": 2.5,
"questions": [{
"_id": ObjectId("5f8af30d5f23667adf3bbaf5"),
"desc": "some text",
},
{
"_id": ObjectId("5f8af3115f23667adf3bbaf8"),
"desc": "some text",
"options": [{
"_id": ObjectId("5f8af3115f23667adf3bbaf9"),
"name": "some name",
"desc": "description 1"
},
{
"_id": ObjectId("5f8af3115f23667adf3bbafa"),
"name": "some name",
"desc": "description 2"
}
]
}
]
}
I've to update the name and desc of the option having id as 5f8af3115f23667adf3bbaf9 which is in the one of the array elements of the question attribute having id as 5f8af30d5f23667adf3bbaf5 which is again part of the data having id as 5f8af2fc5f23667adf3bbaf2
Tried the following query which is getting executed successfully but not updating the option:
Model.findOneAndUpdate({
_id : ObjectId("5f8af2fc5f23667adf3bbaf2"),
"questions._id": ObjectId("5f8af30d5f23667adf3bbaf5"),
"questions.options._id": ObjectId("5f8af3115f23667adf3bbaf9"),
}, {
$set: {
"questions.$[q].options.$[o].order": data.order,
"questions.$[q].options.$[o].definition": data.definition,
"questions.$[q].options.$[o].type": data.type,
},
},
{
arrayFilters: [{ "q._id": ObjectId(qid) }, { "o._id": ObjectId(oid) }]
})
Is tihs possible to do in a single mongoose findOneAndUpdate method?
Your query is correct, I have just hardcoded object id values in array filter and it is updating the documents. I have updated name and desc as u said. Do try this out. One more thing in mongoose u have to specify the object id as "mongoose.Types.ObjectId".
Therefore in your case it would be like "q._id": mongoose.Types.ObjectId("5f8af3115f23667adf3bbaf8").
And one more thing is that you are using findAndUpdate, try using update only depending on your mongoose version
Here is mongoplayground:
https://mongoplayground.net/p/TP5iCTAC5R_
Query:
db.collection.update({
_id: ObjectId("5f8af2fc5f23667adf3bbaf2"),
"questions._id": ObjectId("5f8af3115f23667adf3bbaf8"),
"questions.options._id": ObjectId("5f8af3115f23667adf3bbaf9")
},
{
$set: {
"questions.$[q].options.$[o].name": "anotherName",
"questions.$[q].options.$[o].desc": "anotherDesc"
}
},
{
arrayFilters: [
{
"q._id": ObjectId("5f8af3115f23667adf3bbaf8")
},
{
"o._id": ObjectId("5f8af3115f23667adf3bbaf9")
}
]
})
Output :
[
{
"_id": ObjectId("5f8af2fc5f23667adf3bbaf2"),
"questions": [
{
"_id": ObjectId("5f8af30d5f23667adf3bbaf5"),
"desc": "some text"
},
{
"_id": ObjectId("5f8af3115f23667adf3bbaf8"),
"desc": "some text",
"options": [
{
"_id": ObjectId("5f8af3115f23667adf3bbaf9"),
"desc": "anotherDesc",
"name": "anotherName"
},
{
"_id": ObjectId("5f8af3115f23667adf3bbafa"),
"desc": "description 2",
"name": "some name"
}
]
}
],
"score": 2.5
}
]
{
"_id": "5e28b029a0c8263a8a56980a",
"name": "Recruiter",
"data": [
{
"_id": "5e28b0980f89ba3c0782828f",
"targetLink": "https://www.linkedin.com/in/dan-kelsall-7aa0926b/",
"name": "Dan Kelsall",
"headline": "Content Marketing & Copywriting",
"actions": [
{
"result": 1,
"name": "VISIT"
},
{
"result": 1,
"name": "FOLLOW"
}
]
},
{
"_id": "5e28b0980f89ba3c078283426f",
"targetLink": "https://www.linkedin.com/in/56wergwer/",
"name": "56wergwer",
"headline": "asdgawehethre",
"actions": [
{
"result": 1,
"name": "VISIT"
}
]
}
]
}
Here is one of my mongodb document. I'd like to update data->actions->result
So this is what I've done
Campaign.updateOne({
'data.targetLink': "https://www.linkedin.com/in/dan-kelsall-7aa0926b/",
'data.actions.name': "Follow"
}, {$set: {'data.$.actions.result': 0}})
But it seems not updating anything and even it can't find the document by this 'data.actions.name'
You need the positional filtered operator since the regular positional operator ($) can only be used for one level of nested arrays:
Campaign.updateOne(
{ "_id": "5e28b029a0c8263a8a56980a", "data.targetLink": "https://www.linkedin.com/in/dan-kelsall-7aa0926b/" },
{ $set: { "data.$.actions.$[action].result": 0 } },
{ arrayFilters: [ { "action.name": "Follow" } ] }
)