Need to update an element in array in mongodb - node.js

I am trying to update the store = 465 , AisleName = 59 and set AisleSort = 34 by this update query for the below code
db.getCollection('products').update({'AvailableOnStores.AisleName': { '$eq': '59' }, 'AvailableOnStores.StoreNumber': { '$eq': '465' } }, { '$set': { 'AvailableOnStores.$.AisleSort': 34 } } )
Then it is updating with 34 in the 465 store but we don't have that AisleName in that store. we have that aisle name in store 423. I cannot check element by element, as I am checking all these from json file that contains sort and AisleName for each store.
{
"ProductCode" : "6786777",
"AvailableOnStores" : [
{
"StoreNumber" : "465",
"Price" : "19",
"AisleSort" : 9,
"AisleName" : "Checkout Lane",
"AisleLocations" : [
{
"bayNumber" : 6,
"description" : "Checkout Lane",
}
]
},
{
"StoreNumber" : "423",
"Price" : "1",
"AisleSort" : 5,
"AisleName" : "59",
"AisleLocations" : [
{
"description" : " Aisle 59",
},
{
"description" : "Aisle 25",
},
{
"description" : "Aisle 4",
}
]
}
],
"NotAvailableOnStores" : [],
"IsPricingVaries" : false
}

If you want to update the document in which both of these conditions gets true you should modify your query like this
db.getCollection('products').update(
{
'AvailableOnStores':{
$elemMatch:{'AisleName':{ '$eq': '59' },'StoreNumber':{ '$eq': '465' }}}
},
{
'$set': {'AvailableOnStores.$.AisleSort': 34 }
}
)
For reference read this documentation on mongodb $elemMatch and let me know if you need more help

Related

update the nested array in mongodb using node js

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

Mongoose : Find and Update Multiple Nested Documents

My Documents are as follows.
{
"order_id" : "1",
"payment_status" : false,
"items" : [
{
"item_id" : 1,
"payment_status" : false,
},
{
"item_id" : 2,
"payment_status" : false,
},
{
"item_id" : 3,
"payment_status" : false,
},
]
}
I need to update the fields payment_status for {"order_id":1} and {"item_id" : 1} and {"item_id" : 3}. Also, I need to update the same in bulk for matching conditions. Is this possible in mongoose?
You want to be using $arrayFilters like so:
db.collection.updateMany({
"order_id": "1"
},
{
"$set": {
"items.$[item].payment_status": true
}
},
{
arrayFilters: [
{
"item.item_id": {
$in: [
1,
3
]
}
}
]
})
Mongo Playground

extending an list field in elasticsearch document

I have user_data field in my elasticsearch index document for eg;
sample doc:
user_data : [
{
userid :1,
order_id :32
},
{
userid :8,
order_id : 99
}
]
I have another set of user data in my memory which i want to extend (adding list to list)
data in memory:
preserved_user_data : [
{
userid :991,
order_id :89
},
{
userid :89,
order_id :76
}
]
I want to update that document to :
user_data : [
{
userid :1,
order_id :32
},
{
userid :8,
order_id : 99
},
{
userid :991,
order_id :89
},
{
userid :89,
order_id :76
}
]
i have tried using script ctx._source.user_data += params.preserved_user_data but it makes the document's field empty array.
P.S : I am doing this via parallel bulk using op type : update on ES 7.1.1
A sample query using update script to append array to array in document
Query:
POST index35/_update/tg8DwHAB4HO3_VSZUdzR
{
"script": {
"lang": "painless",
"inline": "if(!ctx._source.containsKey('user_data')){ctx._source['user_data']=[]} for(int i=0;i<params.data.length;i++){ctx._source.user_data.add(params.data[i])}",
"params": {
"data": [
{
"userid": 991,
"order_id": 89
},
{
"userid": 89,
"order_id": 76
}
]
}
}
}
Result:
"hits" : [
{
"_index" : "index35",
"_type" : "_doc",
"_id" : "tg8DwHAB4HO3_VSZUdzR",
"_score" : 1.0,
"_source" : {
"user_data" : [
{
"userid" : 1,
"order_id" : 32
},
{
"userid" : 8,
"order_id" : 99
},
{
"userid" : 991,
"order_id" : 89
},
{
"userid" : 89,
"order_id" : 76
}
]
}
}
]
}

How to update nested array's value in mongoDB or Mongoose

I have data in mongoDB as follows
_id : 5d91caf461f93f13e48ac307,
restaurants : [
{
name : 'grace restaurant',
menus : [
{
menu_name : 'chicken soup',
price : 100
},
{
menu_name : 'Biriyani',
price : 250
},
]
},
{
name : 'river side restaurant',
menus : [
{
menu_name : 'veg lollipop',
price : 47
},
{
menu_name : 'Grill chicken',
price : 210
},
]
}
]
Now, I need to update the river side restaurant's menu "Grill chicken's" price to 310.
How can I do that with mongoose or mongoDB function,I have used lot of different functions but no use, Please help me to find this.
Thank you
We have to use the array filters for the same.
The following is an example:
db.collection.update({},
{
$set:{
"restaurants.$[restaurantFilter].menus.$[menuFilter].price": 310
}
},
{
"arrayFilters":[
{
"restaurantFilter.name":"river side restaurant"
},
{
"menuFilter.menu_name":"Grill chicken"
}
]
})
Before update:
{
"_id" : "5d91caf461f93f13e48ac307",
"restaurants" : [
{
"name" : "grace restaurant",
"menus" : [
{
"menu_name" : "chicken soup",
"price" : 100
},
{
"menu_name" : "Biriyani",
"price" : 250
}
]
},
{
"name" : "river side restaurant",
"menus" : [
{
"menu_name" : "veg lollipop",
"price" : 47
},
{
"menu_name" : "Grill chicken",
"price" : 210
}
]
}
]
}
After update:
{
"_id" : "5d91caf461f93f13e48ac307",
"restaurants" : [
{
"name" : "grace restaurant",
"menus" : [
{
"menu_name" : "chicken soup",
"price" : 100
},
{
"menu_name" : "Biriyani",
"price" : 250
}
]
},
{
"name" : "river side restaurant",
"menus" : [
{
"menu_name" : "veg lollipop",
"price" : 47
},
{
"menu_name" : "Grill chicken",
"price" : 310
}
]
}
]
}

How to get specific data, but not a complete answer in mongodb/nodejs? [duplicate]

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

Resources