This question already has answers here:
MongoDB Add an object to a nested object with condition [duplicate]
Updating a Nested Array with MongoDB
(2 answers)
Closed 4 years ago.
I have the format of:
{
"_id" : ObjectId("5af44cfbe2e96c58ec402efb"),
"username" : "egealpay2",
"email" : "egealpay2#gmail.com",
"fullName" : "ege",
"pnumber" : "",
"oneSignal" : "d427dcdf-7939-4ada-a035-be74e1e45091",
"friends" : [
{
"email" : "baransrc#gmail.com",
"status" : 2
}
],
"alarms" : [
{
"id" : "2",
"title" : "before",
"location" : "default",
"startTime" : "2018-05-16\t\t\t16:29",
"endTime" : "16:29\t\t\t17 - 05 - 2018",
"remindAt" : "17:29\t\t\t15 - 05 - 2018",
"privacy" : "0",
"userORJoinedAlarm" : "1",
"eventJoiners" : [
{
"email" : "ilkersadya#sabanciuniv.edu",
"status" : 1
},
{
"email" : "ilkercankayasss#sabanciuniv.edu",
"status" : 1
},
{
"email" : "ilkearcankaya#sabanciuniv.edu",
"status" : 1
},
{
"email" : "iaaalkercankaya#sabanciuniv.edu",
"status" : 1
}
],
"comments" : [ ]
}
]
}
i would like to set status: 2 of "email" : "ilkersadya#sabanciuniv.edu", its under"alarms:" , "eventJoiners" :which has an id of 2 as"id"`
I have tried using push with $ but couldnt manage to get this working and its been bugging me over 2 hours.
Update i had tried thanks to #Ashish:
dbo.collection("users").findOne( { email: userId } , function(errZer, addedZer) {
dbo.collection("users").findOneAndUpdate( {email: addedID, "alarms.id": eventIDGiv, alarms: { $elemMatch: { id: '2', eventJoiners: { $elemMatch: { email: addedID } } }} },
{ $set: { "alarms.$.eventJoiners.$.status": '2' } , function(err, added) {
got the error
(node:9334) UnhandledPromiseRejectionWarning: MongoError: Too many positional (i.e. '$') elements found in path 'alarms.$.eventJoiners.$.status'
Positional operator ($) can be used only for one level of nested arrays. In your case you have to specify conditions both for alarms and eventJoiners. To do that you can use $[< identifier >] syntax (which is available in MongoDB 3.6+):
db.collection.update(
{ _id: ObjectId("5af44cfbe2e96c58ec402efb") },
{ $set: { "alarms.$[elem1].eventJoiners.$[elem2].status": "2" } },
{ arrayFilters: [ { "elem1.id": "2" }, { "elem2.email": "ilkersadya#sabanciuniv.edu" } ]})
In this case identifiers elem1 and elem2 are used as placeholders for conditions specifed in arrayFilters section.
Related
I need to update a particular element of the nested array in mongoDB
My mongoDB data looks like below. I need to match the value accessid and name to update the status. The input content has
{"accessid" : 1627047023995, "name" : Name 09, "status" : 100 }
The input content may belong to any level
{
"_id" : ObjectId("60fac46ffcbf5287248460a9"),
"levelone" : [
{
"level" : [
{
"name" : "Name 01",
"status" : 5
},
{
"name" : "Name 02",
"status" : 0
},
{
"name" : "Name 03",
"status" : 0
}
],
"accessid" : "1627047023995"
},
{
"level" : [
{
"name" : "Name 09",
"status" : 5
},
{
"name" : "Name 15",
"status" : 3
}
],
"accessid" : "1627047023995"
}
],
"createdAt" : ISODate("2021-07-23T13:30:23.995Z")
}
I have tried to update the status, but it is updating only the first index value - name: Name 01 status. Please guide to resolve the issue.
collections.updateOne({
'levelone.level.accessid': accessid,
'levelone.level.name': name
}, { '$set': { 'levelone.$.level.status': status } }).exec();
you can use arrayFilters positional update,
query with $elemMatch to filter the main document
arrayFilters to define a variable for accessid and b for name
await collections.updateOne({
levelone: {
$elemMatch: {
accessid: accessid,
"level.name": name
}
}
},
{
$set: {
"levelone.$[a].level.$[b].status": status
}
},
{
arrayFilters: [
{ "a.accessid": accessid },
{ "b.name": name }
]
})
Playground
I want to update Itinirary which is embedded subdocument inside the
packages which itself is a embedded document.I tried using index and
was successful like this :
"$set":{'packages.$.itinerary.0.to': "kausaltar"}
but I don't want to use index like 0,1 in itinerary update.Please can you help me.
My JSON schema is like this :
{
"_id" : ObjectId("5e1ca76b9f96d17c449de177"),
"org_id" : "22222222222",
"packages" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17a"),
"region" : "ppopopop",
"itinerary" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17d"),
"id" : 1,
"from" : "ppopopop",
"to" : "ashinnkn",
"mode" : "4444444444",
"day" : 2,
"duration_hrs" : 3
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17c"),
"id" : 2,
"from" : "44444444444",
"to" : "Faketon2",
"mode" : "4444444444",
"day" : 2,
"duration_hrs" : 3
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de17b"),
"id" : 3,
"from" : "55555555555",
"to" : "ashin",
"mode" : "55555555",
"day" : 2,
"duration_hrs" : 3
}
],
"image_url" : "sadfasfsa",
},
{
"_id" : ObjectId("5e1ca76b9f96d17c449de178"),
"region" : "bktll",
"itinerary" : [
{
"_id" : ObjectId("5e1ca76b9f96d17c449de179"),
"id" : 1,
"from" : "mmkkkkm",
"to" : "ashin",
"mode" : "SkkkkA",
"day" : 2,
"duration_hrs" : 3
}
],
"image_url" : "sadfasfsa",
}
]
}
}
I want to update itinerary field inside packages which itself is an embedded document.
And my code is like this :
AgentPackage.update({
"_id" : mongoose.Types.ObjectId("5e1ca76b9f96d17c449de177"),
"packages.region" : "ppopopop",
'packages.itinerary.id': 2,
}, {$set: {'packages.itinerary.$$.from': "test" }}
I am not being able to update.I don't want to use indexing like 0,1 INSIDE query.
Try this :
If you've only one object inside packages with region : "ppopopop", then try this (this should suffice in most cases as you might not have duplicate regions with same name) :
AgentPackage.update({
_id: ObjectId("5e1ca76b9f96d17c449de177"), "packages.region": "ppopopop"
}, { $set: { "packages.$.itinerary.$[item].to": 'kausaltar' } }, {
arrayFilters: [{ 'item.id': 2 }]
})
If you've got multiple objects inside packages with region : "ppopopop", then try this :
AgentPackage.update({
_id: ObjectId("5e1ca76b9f96d17c449de177"), "packages.region": "ppopopop" // Here this "packages.region": "ppopopop" is optional as _id will only bring one document else might be helpful to bring only docs with region: ppopopop right after filter.
}, { $set: { "packages.$[eachPackage].itinerary.$[eachItinerary].to": 'kausaltar' } }, {
arrayFilters: [{ 'eachPackage.region': "ppopopop" }, { 'eachItinerary.id': 2 }]
})
Ref : update-positional-filtered
You can do it with $arrayfilter
db.getCollection("unit").update({_id: ObjectId("5e1ca76b9f96d17c449de177")}, { $set: { "packages.$[t].itinerary.$[d].from": "test" } },
{ arrayFilters: [ { "t.region": "ppopopop" }, {"d.id":15}]})
I know this has been asked a number of times before but I can't seem to find the answer, How to update in nested array but objet in nested array without id???
const hasil = await Setting.update(
{ _id: Id, 'value.name': req.body.name },
{ "$set": { 'value.value': req.body.value } }
)
{
"_id" : 1234567,
"key" : "version",
"name" : "Collection Version",
"value" : [
{
"name" : "categories",
"value" : 7
},
{
"name" : "tag",
"value" : 1
},
{
"name" : "article",
"value" : 3
},
],
}
This question already has answers here:
batchSize field name ignored in Field Projection
(2 answers)
Closed 4 years ago.
I have a collection of the following kind
{
"_id" : ObjectId("5bbb299f06229dddbaab553b"),
"phone" : "+38 (031) 231-23-21",
"date_call" : "2018-10-08",
"adress_delivery" : "1",
"quantity_concrete" : "1",
"state" : "200",
"comments" : "1",
"is_order" : "n",
"date_delivery" : "",
"quantity_orders" : "",
"summ_order" : "",
"profit" : "",
"id" : "0"
}
When requested in the terminal
db.getCollection("customers").find(
{
"$and" : [
{
"date_call" : {
"$lte" : "2018-10-10"
}
},
{
"date_call" : {
"$gte" : "2018-09-24"
}
}
]
},
{
"phone" : 1,
"is_order" : 1
}
);
I get the answer
{
"_id" : ObjectId("5bbb299f06229dddbaab553b"),
"phone" : "+38 (031) 231-23-21",
"is_order" : "n"
}
When requested same query in the nodeJS
client.db(“mongoDB”).collection("customers").find(
{
"$and": [
{
"date_call": {
"$lte" : "2018-10-14"
}
},
{
"date_call": {
"$gte" : "2018-09-24"
}
}
]
},
{
“phone”: 1,
"is_order": 1
}
)
I get a complete answer, not “phone” and “is_order” as set in the query. Please tell me how can I get only the specified data?
You can use project function in this way
client.db("mongoDB").collection("customers").find(
{
"$and": [
{
"date_call": {
"$lte" : "2018-10-14"
}
},
{
"date_call": {
"$gte" : "2018-09-24"
}
}
]
})
.project(
{
"phone": 1,
"is_order": 1
})
.toArray((err, res) => {
//your code here
})
Also base on #Astro comment pass {fields:{"phone": 1, "is_order":1}} as projection object
I have a dataset like this:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 2
},
{
"name" : "#BANANA",
"value" : 1
},
{
"name" : "#ORANGE",
"value" : 5
}
}
want to update only Apple value i.e from 2 to 25. Expected result will be:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 25
},
{
"name" : "#BANANA",
"value" : 1
},
{
"name" : "#ORANGE",
"value" : 5
}
}
I tried the code but this will replace all entry and do only one entry. My code is
db.Collection.update({'sequenceid': 1}, {$set: {'fruit' : {'name': '#APPLE', 'value': parseFloat(25)}}}, function(error, result){
if(error){
console.log('error');
} else {
console.log('success');
}
});
It can produce the result:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 25
}
}//Delete all my rest entry
How I can Do this. I am a newbie on MongoDB
This will update only the first occurrence of record.For reference MongoDB - Update objects in a document's array (nested updating)
db.collection.update({ _id: ObjectId("5a7bf5586262dc7b9f3a8422") ,"fruit.name" : "#APPLE"},
{ $set:
{
"fruit.$.value" : 25
}
})
If you are writing JavaScript query then you can update like this
db.collection.find({'sequenceid': 1}).forEach(function(x){
x.fruit.forEach(function(y){
if(y.name=="#APPLE")
{
y.value = 25
}
})
db.collection.update({_id:x._id},x)
})
db.Collection.update({
_id: ObjectId("5a7bee68996b551034015a15"),
"fruit": {
$elemMatch: {
"name": "#APPLE"
}
}
}, {
$set: {
"fruit.$.value": 25
}
})
In above update operation $elemMatch operator is used to search a value in an array and in $set stage positional operator $ is used to update value of specific key belonging to an array element