How do I query this Mongodb Object? - mongodb

I am trying to query this Mongodb object but can't seem to get to certain data points that I need. How do I get to say the imagePath data? The data is saved in a table called orders. I have tried dot notation i.e. order.cart[0] but can't figure out how to get deeper in the array.
{
"_id": ObjectId("5976b6b11306910658b1ff57"),
"address": "6210 place",
"name": "frank",
"paymentId": "ch_1AjJRVDfJryYeuMpJC80cp5k",
"email": "g#mail.com",
"time": ISODate("2017-07-25T03:10:41.522Z"),
"cart": [
{
"items": {
"5975228a215c0f074b64f58e": {
"item": {
"_id": "5975228a215c0f074b64f58e",
"title": "Bracelet 3",
"imagePath": "https://www.costco.com/wcsstore/CostcoUSBCCatalogAssetStore/category-tiles/pearl-bracelets.jpg",
"description": "This is bracelet 3",
"price": 12,
"__v": 0
},
"qty": 1,
"price": 12
},
"59752242215c0f074b64f58c": {
"item": {
"_id": "59752242215c0f074b64f58c",
"title": "Bracelet 1",
"imagePath": "https://img0.etsystatic.com/160/0/12655872/il_340x270.1187191078_i2ha.jpg",
"description": "This is bracelet 1",
"price": 10,
"__v": 0
},
"qty": 2,
"price": 20
},
"5975226a215c0f074b64f58d": {
"item": {
"_id": "5975226a215c0f074b64f58d",
"title": "Bracelet 2",
"imagePath": "http://media.tiffany.com/is/image/Tiffany/EcomBrowseM/paloma-picasso-knot-bead-bracelet-34946183_963148_ED.jpg?op_usm=1.00,1.00,6.00&defaultImage=NoImageAvailable&&",
"description": "This is bracelet 2",
"price": 5,
"__v": 0
},
"qty": 1,
"price": 5
}
},
"totalQty": 4,
"totalPrice": 37
}
],
"__v": 0
}

const data = {
"address": "6210 place",
"name": "frank",
"paymentId": "ch_1AjJRVDfJ ryYeuMpJC80cp5k",
"email": "g#mail.com",
"cart": [
{
"items": {
"59752 28a215c0f074b64f58e": {
"item": {
"_id": "5975228a215c0f074b64f58e",
"title": "Bracelet 3",
"imagePath": "https:// www.costco.com/wcsstore/CostcoUSBCCatalogAssetStore/category-tiles/pearl-bracelets.jpg",
"description": "This is brace let 3",
"price": 12,
"__v": 0
},
"qty": 1,
"price": 12
},
"59752242215c0f074b64f58c": {
"item": {
"_id": "597522 42215c0f074b64f58c",
"title": "Bracelet 1",
"imagePath": "https://img0.etsystatic.com/160/0/12655872/il_340x270.11871 91078_i2ha.jpg",
"description": "This is bracelet 1",
"price": 10,
"__v": 0
},
"qty": 2,
"price": 20
},
"5975226a2 15c0f074b64f58d": {
"item": {
"_id": "5975226a215c0f074b64f58d",
"title": "Bracelet 2",
"imagePath": "http://media .tiffany.com/is/image/Tiffany/EcomBrowseM/paloma-picasso-knot-bead-bracelet-34946183_963148_ED.jpg?op_usm=1.00,1.00,6.0 0&defaultImage=NoImageAvailable&&",
"description": "This is bracelet 2",
"price": 5,
"__v": 0
},
"qty": 1,
"price": 5
}
},
"totalQty": 4,
"totalPrice": 37
}
],
"__v": 0
};
console.log('looping through Object.keys')
Object.keys(data.cart[0].items).forEach(key => {
const cartItem = data.cart[0].items[key];
console.log('cartItem.item.imagePath', cartItem.item.imagePath)
})
console.log('looping through Object.values')
Object.values(data.cart[0].items).forEach(cartItem=> {
console.log('cartItem.item.imagePath', cartItem.item.imagePath)
})
Since your cart item.items is an object. You can leverage Object.keys or Object.values to loop through an object properties.

Related

How to properly insert documents into a collection using the MongoDB Web Shell

I am having some trouble inserting a collection of documents into a MongoDB Web Shell from the mongodb site.
The link provided: https://docs.mongodb.com/manual/tutorial/insert-documents/
Here is what I have for a simple example:
db.FirstExample.insertMany ([
{ "Date": "2001-01-01", "Description": "Airfare", "Amount": "500.34" },
{ "Date": "2001-01-01", "Description": "Hotel", "Amount": "200" },
{ "Date": "2001-01-01", "Description": "Taxi Fare", "Amount": "100.00" },
{ "Date": "2001-01-01", "Description": "Long Distance Phone Charges", "Amount": "57.89" },
{ "Date": "2001-01-01", "Description": "Food", "Amount": "82.19" },
{ "Date": "2001-01-02", "Description": "Food", "Amount": "17.89" },
{ "Date": "2001-01-02", "Description": "Personal Items", "Amount": "32.54" },
{ "Date": "2001-01-03", "Description": "Taxi Fare", "Amount": "75.00" },
{ "Date": "2001-01-03", "Description": "Food", "Amount": "36.45" },
{ "Date": "2001-01-03", "Description": "New Suit", "Amount": "750.00" }
]);
When I run this collection into the MongoDB Web Shell, it works perfectly. Now here's the trouble, I want to include one more element called "ExpenseItem". When I enter the new code snippet, I get an error.
db.FirstExample.insertMany ([
{ "ExpenseItem:"
{ "Date": "2001-01-01", "Description": "Airfare", "Amount": "500.34" },
{ "Date": "2001-01-01", "Description": "Hotel", "Amount": "200" },
{ "Date": "2001-01-01", "Description": "Taxi Fare", "Amount": "100.00" },
{ "Date": "2001-01-01", "Description": "Long Distance Phone Charges", "Amount": "57.89" },
{ "Date": "2001-01-01", "Description": "Food", "Amount": "82.19" },
{ "Date": "2001-01-02", "Description": "Food", "Amount": "17.89" },
{ "Date": "2001-01-02", "Description": "Personal Items", "Amount": "32.54" },
{ "Date": "2001-01-03", "Description": "Taxi Fare", "Amount": "75.00" },
{ "Date": "2001-01-03", "Description": "Food", "Amount": "36.45" },
{ "Date": "2001-01-03", "Description": "New Suit", "Amount": "750.00" }
}
]);
The error is this:
E QUERY [js] uncaught exception: SyntaxError: missing : after property id :
Why am I getting the error? Isn't the ":" already next to the "ExpsenseItem"? What key detail am I missing for this code snippet not running in the MongoDb Web Shell?
The colon separating they key ExpenseItem from the rest of the document is inside the quotes so is considered part of the key. To nest the documents as they are you would need to put them inside an array. As so:
{ "ExpenseItem" : [
{ "Date": "2001-01-01", "Description": "Airfare", "Amount": "500.34" },
{ "Date": "2001-01-01", "Description": "Hotel", "Amount": "200" },
{ "Date": "2001-01-01", "Description": "Taxi Fare", "Amount": "100.00" },
{ "Date": "2001-01-01", "Description": "Long Distance Phone Charges", "Amount": "57.89" },
{ "Date": "2001-01-01", "Description": "Food", "Amount": "82.19" },
{ "Date": "2001-01-02", "Description": "Food", "Amount": "17.89" },
{ "Date": "2001-01-02", "Description": "Personal Items", "Amount": "32.54" },
{ "Date": "2001-01-03", "Description": "Taxi Fare", "Amount": "75.00" },
{ "Date": "2001-01-03", "Description": "Food", "Amount": "36.45" },
{ "Date": "2001-01-03", "Description": "New Suit", "Amount": "750.00" }
]
}
This document will insert but it is now a single document.

Category hierarchy in mongodb

My document structure is as follows:
[
{
"_id": ObjectId("54d81827e4a4449d023b4e34"),
"name": "Refridgerator",
"parent": null,
"slug": "refridgerator"
},
{
"_id": ObjectId("54d818227e4a4449d023b4e34"),
"name": "Generator",
"parent": null,
"slug": "generator",
},
{
"_id": ObjectId("54dc38bcse4a4449d023b4e58"),
"name": "Bolt",
"slug": "bolt",
"parent": ObjectId("54d818227e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e58"),
"name": "Ice Cream",
"slug": "ice-cream",
"parent": ObjectId("54d81827e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc3705e4a4449d023b4e56"),
"name": "Chocolate",
"slug": "chocolate",
"parent": ObjectId("54d81827e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e68"),
"name": "Mango Cream",
"slug": "mango-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e58")
},
{
"_id": ObjectId("54dc38bc74a4449d023b4e68"),
"name": "Mango Cream Cream",
"slug": "mango-cream-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e68")
},
]
I’m making a category hierarchy using mongodb and its like parent-child relationship. Category is of 4 level.
Now I wish to query for _id = ‘54d81827e4a4449d023b4e34’ and should get back all the child categories.
I’m unable to get the json structured with parent – child relations.
In previous asked question does not output the required result.
Expected Output:
[
{
"_id": ObjectId("54d81827e4a4449d023b4e34"),
"name": "Refridgerator",
"parent": null,
"slug": "refridgerator",
"subCategory": [
{
"_id": ObjectId("54dc3705e4a4449d023b4e56"),
"name": "Chocolate",
"parent": ObjectId("54d81827e4a4449d023b4e34"),
"slug": "chocolate"
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e58"),
"name": "Ice Cream",
"parent": ObjectId("54d81827e4a4449d023b4e34"),
"slug": "ice-cream",
'subsubcategory':[
{
"_id": ObjectId("54dc38bce4a4449d023b4e68"),
"name": "Mango Cream",
"slug": "mango-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e58"),
'subsubsubcategory':[
{
"_id": ObjectId("54dc38bc74a4449d023b4e68"),
"name": "Mango Cream Cream",
"slug": "mango-cream-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e68")
},
]
}
]
}
]
},
{
"_id": ObjectId("54d818227e4a4449d023b4e34"),
"name": "Generator",
"parent": null,
"slug": "generator",
"subCategory": [
{
"_id": ObjectId("54dc38bcse4a4449d023b4e58"),
"name": "Bolt",
"slug": "bolt",
"parent": ObjectId("54d818227e4a4449d023b4e34")
},
]
}
]

How to check $exists in one to many relationship mongodb sails js?

Is there any way to find records that collection is empty?
For example please find below array. I want only that records with index "companydata" is empty. and also how can i get data that does not have empty "companydata" data.
Thanks in advance.
[
{
"company_id": {
"company_name": "C2",
"slug": "c2",
"is_organized": 1,
"status": "1",
"id": "5adf158f547f7f0314ca8b56",
"companydata": []
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ae014e7432e85298081be0b"
},
{
"company_id": {
"company_name": "My Compnay",
"slug": "my-compnay",
"is_organized": 1,
"status": "1",
"id": "5ad442d98a0e0c1358ca93df",
"companydata": [
{
"name": "Bhavesh Amin",
"company_id": "5ad442d98a0e0c1358ca93df",
"status": "0",
"id": "5ad442da8a0e0c1358ca93e0"
}
]
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ae01388432e85298081bdf8"
},
{
"company_id": {
"company_name": "Organization Name",
"slug": "organization-name",
"is_organized": 1,
"status": "1",
"id": "5ad08f9b938d1131eceea624",
"companydata": [
{
"name": "Helen H. Langley",
"company_id": "5ad08f9b938d1131eceea624",
"status": "1",
"id": "5ad08f9b938d1131eceea625"
}
]
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ad42a5f52851a2b1449db2d"
},
]

Update single sub document in multiple array in mgo

I have following mongodb (3.4.x) document, i code in golang with mgo driver
{
"id": "5981d4c2795a1b4a801ee027",
"scenarioId": "59804b10d8ee910085e33865",
"messages": [
{
"id": "5981d4c2795a1b4a801ee028",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee029",
"to": {
"email": "some#email.com"
},
"channel": "EMAIL",
"toType": "EMAIL",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02a",
"to": {
"phone": "+381631891245"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02b",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee02c",
"to": {
"phone": "+123456789"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"messageStages": [
{
"id": "5981d4c2795a1b4a801ee033",
"validityPeriod": 5,
"validityPeriodTimeUnit": "MINUTES",
"providerId": 5,
"email": {
"text": "this is the email text",
"subject": "and here the email subject"
},
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
]
}
and I know the value of messages.$.toQueue.id, where i want to update status.id in the related toQueue Array Item.
I tried to do it that way:
query = bson.M{
"messages.toQueue._id": toQueueId,
}
update = bson.M{
"$set": bson.M{
"messages.$.toQueue.$.status.id": status.Id,
"messages.$.toQueue.$.status.name": status.Name,
"messages.$.toQueue.$.status.groupId": status.GroupId,
"messages.$.toQueue.$.status.groupName": status.GroupName,
"messages.$.toQueue.$.status.description": status.Description,
},
}
err = cr.Update(query,update)
but multiple $ are not allowed. Without it's also not updateable.
Is there any way to update only the subdocument, which i found in query ?
Neil Lunn gave the right answer.
It's not possible to work with nested arrays the way I tried to do. And he is also right, that problem is coming from design mistake.
So I changed it as him and Markus W Mahlberg suggested to move the toQueue part in a separate collection, with messageId as a reference.

Nested grouping of array

There are 3 master collection of category , subcategory and criteria each, i will be building framework with any possible combination of category , subcategory and criteria which will be stored as below-
framework document is added below having list of criteriaconfig as embedded object which further have single object of category , subcategory and criteria. you can refer criteriaconfig as link table that u call in mysql.
[
{
"id": "592bc3059f3ad715002b2331",
"name": "Framework1",
"description": "framework 1 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1",
"deleted": false,
"createdDate": 1495019359558
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
},
{
"id": "592bc3059f3ad715002b232e",
"category": {
"id": "591c2f5faa187956b2d0fb37",
"name": "Process",
"description": "Enagagement"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb81",
"name": "COMM / BRANDING",
"description": "COMM / BRANDING"
},
"criteria": {
"id": "591c2f5faa187956b2d0fba9",
"name": "Company representative forgets about customer on hold",
"measure": ""
}
} ]
},
{
"id": "592bc3059f3ad715002b2332",
"name": "Framework2",
"description": "framework 2 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
}
]
}
]
i need a view containing framework that will contain all list of category and inside category there will be list of added subcategory and inside subcategory will have list of criteria for single framework.
expected result -
[
{
"id": "f1",
"name": "Framework1",
"description": "framework 1 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb1",
"name": "subCat1",
"description": "subCat1",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
},
{
"id": "f2",
"name": "Framework2",
"description": "framework 2 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb4",
"name": "subCat5",
"description": "subCat5",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
}
]
Note - Category document doesn't have any reference to subcategory and same way subcategory doesn't have any reference to criteria object currently as they are master data and are generic , framework is created with their combination dynamically.
If you want to try to do all the work in the aggregation, you could group first by subcategory, then by category like:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$project:{
_id:0,
category:"$criteriaConfigs.category",
subCategory:"$criteriaConfigs.subCategory",
criteria:"$criteriaConfigs.criteria"
}},
{$group:{
_id:{"category":"$category","subCategory":"$subCategory"},
criteria:{$addToSet:"$criteria"}
}},
{$group:{
_id:{"category":"$_id.category"},
subCategories:{$addToSet:{subCategory:"$_id.subCategory",
criteria:"$criteria"}}
}},
{$project:{
_id:0,category:"$_id.category",
subCategories:"$subCategories"
}}
])
Depending on how you plan to us the return data, it may be more efficient to return each unique combination:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$group:{
_id:{
category:"$criteriaConfigs.category.name",
subCategory:"$criteriaConfigs.subCategory.name",
criteria:"$criteriaConfigs.criteria.name"
}
}},
{$project:{
_id:0,
category:"$_id.category",
subCategory:"$_id.subCategory",
criteria:"$_id.criteria"
}}
])
I'm not sure from your question what shape you are expecting the return data to have, so you may need to adjust for that.