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
}
]
}
}
]
}
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 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
}
]
}
]
}
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
There are multiple collections one of these are.
users
place
The document stored in the database which is given below.
{
"_id" : "1eca51f0-538d-11e8-89fc-d125355b590d",
"organization" : [
{
"associationIds" : {
"dObjectIds" : [
{
"dObjectData" : {
"objectId" : "fd047ddf-61c2-4df2-8241-62af0399c8c1",
"objectName" : "shift",
"dObjectId" : "49492544-e4e3-491b-b967-a6f62330da3f"
}
}
]
},
"organizationId" : "1c3f6150-538d-11e8-89fc-d125355b590d",
"privelege" : "Admin",
"organizationName" : "ABC"
},
{
"associationIds" : {
"dObjectIds" : [
{
"dObjectData" : {
"objectId" : "ad047ddf-61c2-4df2-8241-62af0399c5c1",
"objectName" : "shift",
"dObjectId" : "38492544-e4e3-491b-b967-a6f62330da3f"
}
},
{
"dObjectData" : {
"objectId" : "fd047ddf-61c2-4df2-8241-62af0399c8c2",
"objectName" : "department",
"dObjectId" : "49492544-e4e3-491b-b967-a6f62330da1f"
}
}
]
},
"organizationId" : "1c3f6150-538d-11e8-89fc-d125355b591d",
"privelege" : "Manager",
"organizationName" : "XYZ"
}
]}
I'm using these query.
db.users.aggregate([
{$match: {'_id': '1eca51f0-538d-11e8-89fc-d125355b590d'}},
{$unwind :'$organization'},
{$match:{'organization.organizationId':'1c3f6150-538d-11e8-89fc-d125355b591d'}},
{$unwind:'$organization.associationIds.dObjectIds'},
{'$lookup': {
'from': 'places',
localField:'organization.associationIds.dObjectIds.dObjectData.dObjectId',
foreignField: 'dObjectData.dObjectId',
as: 'associationData'
}
},
{'$project': {
'associationData': 1
}
}
])
I have used $unwind two times in a query which has more expensive.Is there any way or operation which can we use instead of multiple times of $unwind.
NOTE: I waana result like this(result of associationData which get the velue from other collection so I used $lookup)
{
_id" : "c6114ee0-c82f-11e6-9b1e-6140212f8693",
"associationData" : [
{
"_id" : "f09f5d70-ad7e-11e7-87bd-cd873956707e",
"dObjectData" : {
"departmentName" : "CEO & Directors",
"dObjectId" : "ab034106-ad7d-11e7-abc4-cec278b6b50a",
"objectName" : "Departments",
"objectId" : "63735ee2-ad79-11e7-abc4-cec278b6b50a",
"updatedOn" : ISODate("2017-10-10T11:20:37.255+05:30"),
"addedOn" : ISODate("2017-10-10T11:20:37.255+05:30")
},
"associationIds" : {
"organizationId" : "af39bc69-1938-4149-b9f7-f101fd9baf73",
"placeIds" : [ ],
"assignmentIds" : [ ],
"beaconIds" : [ ],
"userIds" : [ ]
}
}]}
I'll be very thankful.
I have a collection called "products" which has an array of "bids" objects.
I want to find out the Maximum bid for each product, for this I am aggregating Products on $max with $bids.bidamount field. However this is only giving me the largest bid amount. How do I project all the bid fields for the max aggregation.
Here is a sample document
{
"_id" : ObjectId("58109a5138fe12215cfdc064"),
"product_id" : 2,
"item_name" : "Auction Item1",
"item_description" : "Test",
"seller_name" : "ak#gmail.com",
"item_price" : "20",
"item_quantity" : 7,
"sale_type" : "Auction",
"posted_at" : "2016:10:26 04:58:09",
"expires_at" : "2016:10:30 04:58:09",
"bids" : [
{
"bid_id" : 1,
"bidder" : "ak#gmail.com",
"bid_amount" : 300,
"bit_time" : "2016:10:26 22:36:29"
},
{
"bid_id" : 2,
"bidder" : "ak#gmail.com",
"bid_amount" : 100,
"bit_time" : "2016:10:26 22:37:29"
}
],
"orders" : [
{
"buyer" : "ak#gmail.com",
"quantity" : "2"
},
{
"buyer" : "ak#gmail.com",
"quantity" : "3"
}
]
}
Here is my mongo query:
db.products.aggregate([
{
$project: {
bidMax: { $max: "$bids.bid_amount"}
}
}
])
which gives the following result:
{
"_id" : ObjectId("58109a5138fe12215cfdc064"),
"bidMax" : 300
}
db.products.aggregate([{$unwind:"$bids"},{$group:{_id:"$_id", sum:{$sum:"$bids.bid_amount"}}},{$project:{doc:"$$ROOT", _id:1, sum:1}, {$sort:{"sum":-1}},{$limit:1}]),
which return something like { "_id" : ObjectId("5811b667c50fb1ec88227860"), "sum" : 600, doc:{your document....} }
This should do it:
db.products.aggregate([{
$unwind: '$bids'
}, {
$group: {
_id: '$products_id',
maxBid: {
$max: '$bids.bid_amount'
}
}
}])
db.collectionName.aggregate(
[
{
$group:
{
_id: "$product_id",
maxBidAmount: { $max: "$bids.bid_amount" }
}
}
]
)
Hey use this query, you will get the result.