Mongodb - Update the value of object's array's key value - mongodb

I have below documents in the collection.
{
"_id" : ObjectId("5c98760c27b9fb1266f996b3"),
"user_id" : ObjectId("5c8109785b9a5427b167542a"),
"permissions" : [
{
"dashboard" : [
"Pie Chart",
"Bar Chart"
],
"product management" : [
"update",
"delete",
"list",
"insert"
],
"app user listing" : [
"insert",
"update",
"delete",
"list"
]
}
]
}
I am trying to perform below query:
db.user_permissions.update(
{ user_id: ObjectId("5c8740860c5dcf6c615c1ba3") },
{
"permissions.app user listing": ['inserts']
}
)
what I want to do is to update the value of "app user listing".
Any help appreciated.
EDIT:
This is what I want
Expected Outpupt:
{
"_id" : ObjectId("5c98760c27b9fb1266f996b3"),
"user_id" : ObjectId("5c8109785b9a5427b167542a"),
"permissions" : [
{
"dashboard" : [
"Pie Chart",
"Bar Chart"
],
"product management" : [
"update",
"delete",
"list",
"insert"
],
"app user listing" : [
"inserts"
]
}
]
}
I want to update value of given key with array.

This works on all versions on mongo, you need second argument for find,
db.myColl.update(
{
"user_id" : ObjectId("5c8109785b9a5427b167542a"),"permissions.app user listing":["insersssts"]
},
{
$set: {
"permissions.$.app user listing":["insertss"]
}
});

Try as below:
db.user_permission.update(
{
"user_id" : ObjectId("5c8109785b9a5427b167542a")
},
{
$set: {
"permissions.$[].app user listing": ['inserts']
}
},
{
upsert:false
}
)
Data before running query :
{
"_id" : ObjectId("5c98760c27b9fb1266f996b3"),
"user_id" : ObjectId("5c8109785b9a5427b167542a"),
"permissions" : [
{
"dashboard" : [
"Pie Chart",
"Bar Chart"
],
"product management" : [
"update",
"delete",
"list",
"insert"
],
"app user listing" : [
"insert",
"update",
"delete",
"list"
]
}
]
}
After running query:
{
"_id" : ObjectId("5c98760c27b9fb1266f996b3"),
"user_id" : ObjectId("5c8109785b9a5427b167542a"),
"permissions" : [
{
"dashboard" : [
"Pie Chart",
"Bar Chart"
],
"product management" : [
"update",
"delete",
"list",
"insert"
],
"app user listing" : [
"inserts"
]
}
]
}

Related

ElasticSearch filter on array along with multiple match queries

I am trying to filter the documents based on some tags and subcategory.
Some documents:
[{
"_id" : "2oukjh8o9qy2ejhasdkqwe",
"productName" : "ASSORTED DOUGHNUT 1PC",
"productSubCategory" : [
{
"label" : "Veg",
"imageUrl" : "/catImg/fandA.svg"
}
],
"isVisible" : true,
"tags" : [
{
"tagImageUrl" : " ",
"label" : "Favorites",
"tag" : "favorites"
}
]
},
{
"_id" : "638daf9f42e6efc7f06641c2",
"isVisible" : true,
"productName" : "FILTER COFFEE",
"productSubCategory" : [
{
"_id" : ObjectId("638daf18ed445826c06a7328"),
"label" : "Veg"
}
],
"tags" : [
{
"tagImageUrl" : " ",
"label" : "Trending",
"tag" : "trending"
},
{
"tagImageUrl" : " ",
"label" : "Favorites",
"tag" : "favorites"
},
{
"tagImageUrl" : " ",
"label" : "Cabin Friendly",
"tag" : "cabinfriendly"
}
]
},
{
"_id" : "6389d7f942e6efc7f05d51e0",
"isVisible" : true,
"productName" : "ILLY DOPPIO",
"productSubCategory" : [
{
"_id" : ObjectId("638d97236612ca5d5ceb53b9"),
"label" : "Non-Veg"
}
],
"tags" : [
{
"tagImageUrl" : " ",
"label" : "Cabin Friendly",
"tag" : "cabinfriendly"
}
]
}]
Query I am trying
{
"query": {
"bool": {
"must": [
{
"match": {
"productSubCategory.label": {
"query": "Veg",
"operator": "and"
}
}
},
{
"match": {
"isVisible": true
}
}
],
"filter": {
"terms": {
"tags.tag": [
"favorites",
"cabinfriendly"
]
}
}
}
}
}
Requirement
The result documents must have any of the tags.tag provided in the query. Must have isVisible as true and productSubCategory.label as provided in the query.
With the above query I am getting Non-Veg items as well.
Because you are using match query which will do the free text search and it will match with the non-veg as well. You can use term query with keyword type insted of match query like shown below:
{
"query": {
"bool": {
"must": [
{
"term": {
"productSubCategory.label.keyword": {
"value": "Veg"
}
}
},
{
"match": {
"isVisible": true
}
}
],
"filter": {
"terms": {
"tags.tag": [
"favorites",
"cabinfriendly"
]
}
}
}
}
}
Please note that i have replace field name productSubCategory.label with productSubCategory.label.keyword

How to convert existing array of string to custom object array in mongodb?

I have some existing data and I want to update it but I can't able to build a query for that.
I want to convert and update Options field which is string array to object array.
Is it possible or not?
I tried arrayToObject but it doesn't work
Below is my existing record:
{
"_id" : ObjectId("5b6455d9c006ae9d142b0da8"),
"PartnerId" : "585938e3d4e9dac9bb2b09c6",
"BusinessID" : NumberLong(98),
"Responses" : [
{
"QID" : 1,
"Order" : 1,
"Question" : "Contact Information 1",
"Options" : [
"First Name",
"Address",
"Email",
"Phone"
],
"Answers" : [
"First Name",
"111, Dublin, California, 94568",
"forms1#vagaro.com",
"111"
]
},
{
"QID" : 8,
"Order" : 6,
"Question" : "Contact Information 2",
"Options" : [
"Address",
"Email"
],
"Answers" : [
"5000 Estate Enighed, Independence, Kansas, 67301"
]
}
]
}
Expected result:
{
"_id" : ObjectId("5b6455d9c006ae9d142b0da8"),
"PartnerId" : "585938e3d4e9dac9bb2b09c6",
"BusinessID" : NumberLong(98),
"Responses" : [
{
"QID" : 1,
"Order" : 1,
"Question" : "Contact Information 1",
"Options" : [
{Option:"First Name", Order:1},
{Option:"Address", Order:2},
{Option:"Email", Order:3},
{Option:"Phone", Order:4}
],
"Answers" : [
"First Name",
"111, Dublin, California, 94568",
"forms1#vagaro.com",
"111"
]
},
{
"QID" : 8,
"Order" : 6,
"Question" : "Contact Information 2",
"Options" : [
{Option:"Address", Order:1},
{Option:"Email" , Order:2}
],
"Answers" : [
"5000 Estate Enighed, Independence, Kansas, 67301"
]
}
]
}
Please help me.
Thanks
You can use Aggregation like follows. I used mongo shell with the same document you described.
db.test.aggregate([
{ $match: {} },
{
$project: {
_id: "$_id",
PartnerId: "$PartnerId",
BusinessID: "$BusinessID",
Responses: {
$map: {
input: "$Responses",
as: 'response',
in: {
"QID" : "$$response.QID",
"Order" : "$$response.Order",
"Question" : "$$response.Question",
"Options" : {
$map: {
input: "$$response.Options",
as: 'option',
in: {
Option: "$$option",
Order: {
$sum: [
{
$indexOfArray: [
"$$response.Options",
"$$option"
]
},
1
]
}
}
}
},
"Answers" : "$$response.Answers"
}
}
}
}
},
{ $out: 'output' }
])
Will output the desired documents to the collection output. You can check it and rename it later or just specify another collection name in the $out stage if you want to override/create another collection.

How to merge document in mongodb based on an Id

Is there a way in mongoDb to merge documents based on id. For eg:
/*1*/{
"id" : "xxxxxx",
"pages" : {
"name" : "Page50-50",
"pageid" : "Page50-50",
"icon" : "/images/cmstemplates/2column.png",
"children" : []
},
"permissions" : [
{
"grpName" : "Admin",
"grants" : [
"View",
"Delete",
"Edit"
]
},
{
"grpName" : "Users",
"grants" : [
"View"
]
}
]
}
/*2*/
{
"id" : "xxxxxx",
"pages" : {
"name" : "AboutUs",
"pageid" : "AboutUs",
"icon" : "/images/cmstemplates/1column.png",
"children" : []
},
"permissions" : [
{
"grpName" : "Student",
"grants" : [
"View",
"Delete"
]
}
]
}
Expected Output:
{
"id" : "xxxxxx",
"pages" : [{
"name" : "Page50-50",
"pageid" : "Page50-50",
"icon" : "/images/2column.png",
"children" : [],
"permissions" : [
{
"grpName" : "Admin",
"grants" : [
"View",
"Delete",
"Edit"
]
},
{
"grpName" : "Users",
"grants" : [
"View"
]
}
]
},{
"name" : "AboutUs",
"pageid" : "AboutUs",
"icon" : "/images/1column.png",
"children" : [],
"permissions" : [
{
"grpName" : "Student",
"grants" : [
"View",
"Delete"
]
}
]
}]
}
The permissions params in the expected output should come inside pages, and pages should group into an array. I used $group and was able to group the pages, but i am not able to figure out how can i add permissions param inside pages. I am using mongodb 3.2.
Thanks.
Use $group
db.getCollection('Collection').aggregate([{
$group: {
"_id": "$_id",
"pages": {
$push: "$pages"
}
}
}])

How to change the response in MongoDB using translatable fields

I am looking for the way how to resolve this and I can't find it. I appreciate your help.
I have a collection with products like:
[
{
"name": [
{ "es": "Producto 1" },
{ "en": "Product 1" }
]
"reference": "PR1",
"price": "20",
"description": [
{ "es": "Descripción 1" },
{ "en": "Description 1" }
]
}
]
And I would like to do:
db.products.aggregate(); // Find by language es for example:
And get:
[
{
"name": "Producto 1",
"reference": "PR1",
"price": "20",
"description": "Descripción 1"
}
]
Thanks very much.
I would suggest a schema change though to this:
[
{
"name" : [
{
"language" : "es",
"description" : "Producto 1"
},
{
"language" : "en",
"description" : "Product 1"
}
],
"reference" : "PR1",
"price" : "20",
"description" : [
{
"language" : "es",
"description" : "Descripción 1"
},
{
"language" : "en",
"description" : "Description 1"
}
]
}
]
cause then you could actually group by the language in your case.
If this is possible then you could do the following:
db.products.aggregate([
{$unwind: "$someName"},
{$unwind: "$someName.name"},
{$unwind: "$someName.description"},
{
$group: {
_id: {namelang: "$someName.name.language", namedesc: "$someName.description.language"},
name: {$first: "$someName.name.description"},
reference: {$first: "$someName.reference"},
price: {$first: "$someName.price"},
description: {$first: "$someName.description.description"}
}
},
{
$match: {
"_id.namelang": "en",
"_id.namedesc": "en"
}
}
])
FYI since you didn't provided your complete json I created one random. Here is the complete schema:
{
"_id" : ObjectId("59ea07a600f5db2660dbf162"),
"someName" : [
{
"name" : [
{
"language" : "es",
"description" : "Producto 1"
},
{
"language" : "en",
"description" : "Product 1"
}
],
"reference" : "PR1",
"price" : "20",
"description" : [
{
"language" : "es",
"description" : "Descripción 1"
},
{
"language" : "en",
"description" : "Description 1"
}
]
}
]
}

MongoDB: how to delete an object from a document in a nested array

My doc is like this
"page_elements" : [
{
"type" : "gallery",
"words" : [
"gallery",
"photos"
]
},
{
"type" : "cart",
"words" : [
"cart",
"shop"
]
},
{
"type" : "Privacy",
"words" : [
"privacy",
"policy",
"privacy policy"
]
},
{
"type" : "cart",
"words" : [
"cart",
"shopping cart",
"buy now",
"add to cart",
"add to basket"
]
}
by mistake, I've updated cart two times. now, i need to remove the first cart in the array and keep the rest of the document.
Here, I need to delete
{
"type" : "cart",
"words" : [
"cart",
"shop"
]
}
I tried this..
db.ds_master_language_words.remove( { "page_elements.type" : "cart" } )
You don't want to remove, you want to update. $unset will get rid of the field and you know the position:
db.ds_master_language_words.update(
{ <your_document_id_match > },
{ $unset: { "page_elements.1": ""}}
)
That will set to null in the array, but now that is easy to remove with $pull:
db.ds_master_language_words.update(
{ <your_document_id_match > },
{ $pull: { "page_elements": null }}
)
Also see the documentation for the update method
http://docs.mongodb.org/manual/reference/method/db.collection.update/
You can do this with $pull by giving it a page_elements value that matches the array element to remove:
db.ds_master_language_words.update({}, {
$pull: {page_elements: {
"type": "cart",
"words": ["cart", "shop"]
}}})