Related
The data :
{
"_id" : ObjectId("5da6ea7228cc5e07b48173b5"),
"name" : "Joshi",
"email" : "joshiga#gmail.com",
"password" : "4emc8122",
"phone" : "60000000001",
"myAddresses" : [
{
"_id" : ObjectId("5da6eb511e21bf07ce33b868"),
"address" : "Office",
"firstName" : "joshi",
"lastName" : "g",
"country" : "India",
"city" : "VISAKHAPATNAM",
"province" : "Andhra Pradesh",
"postalCode" : 521344,
"phoneNumber" : 8100000006.0,
"address1" : "D.no:12,",
"address2" : "santhi nagar, gurudwara"
},
{
"_id" : ObjectId("5da6ec5e20a5db07da27fbc6"),
"address" : "Home",
"firstName" : "joshi",
"lastName" : "g",
"country" : "India",
"city" : "Vijayawada",
"province" : "Andhra Pradesh",
"postalCode" : 521333,
"phoneNumber" : 8000000006.0,
"address1" : "D.no:11-41,",
"address2" : "main road, kalidindi"
}
],
"__v" : 0
}
You can use the following:
CollectionName.update({'myAddresses._id': "Your ID"}, {'$set': {
'myAddresses.$. address': 'updated Address'
}}, function(err) { ...
ModelName.update({
"_id": req.params.id,
"myAddresses": {
"$elemMatch": {
"_id": req.params.addressId
}
}
}, {
$set: {
"myAddresses.$.address": req.body.address,
"myAddresses.$.firstName": firstName,
//add all fields
}
})
I have one collection called "location". in this collection all child and parent collection are stores. now I want to create a query who returns me parent to child spaces separated string.
Collection
businessId: { type: mongoose.Schema.Types.ObjectId, ref: 'admin' },
parentId: { type: mongoose.Schema.Types.ObjectId, ref: 'location' },
name: { type: String },
image: { type: String },
imageManipulation: { type: String },
locationColor: [{ range: { type: String }, color: { type: String } }],
area: {},
settings: {},
status: { type: String, enum: [0, 1], default: 1 },
isChild: { type: String, enum: [0, 1] },
parentPosition: { type: String }
In the above collection, you can see parentId field. if the location is a child then it have parentId. if the location is a parent then parentId will null. parent location can N level child location.
Collection Data
[{
"_id" : ObjectId("5cee1002a01ad50f5c222982"),
"status" : "1",
"name" : "Ground Floor",
"settings" : {
"zoom" : "0",
"positionX" : "0",
"positionY" : "0",
"width" : "498",
"height" : "498"
},
"image" : "1559105538977.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:52:18.999Z"),
"createdAt" : ISODate("2019-05-29T04:52:18.999Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee103ca01ad50f5c222983"),
"status" : "1",
"name" : "Kitchen",
"settings" : {
"zoom" : "0",
"positionX" : "0",
"positionY" : "0",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":3,\"points\":[{\"x\":20,\"y\":178},{\"x\":19,\"y\":75},{\"x\":56,\"y\":71},{\"x\":57,\"y\":52},{\"x\":80,\"y\":18},{\"x\":138,\"y\":17},{\"x\":165,\"y\":52},{\"x\":165,\"y\":94},{\"x\":174,\"y\":96},{\"x\":173,\"y\":179}],\"fill\":\"rgba(178,40,40,0.58)\"}",
"parentId" : ObjectId("5cee1002a01ad50f5c222982"),
"image" : "1559105596975.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:53:16.990Z"),
"createdAt" : ISODate("2019-05-29T04:53:16.990Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee1078a01ad50f5c222984"),
"status" : "1",
"name" : "Cbot",
"settings" : {
"zoom" : "0",
"positionX" : "0",
"positionY" : "0",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":3,\"points\":[{\"x\":20,\"y\":311},{\"x\":17,\"y\":59},{\"x\":84,\"y\":58},{\"x\":88,\"y\":312}],\"fill\":\"rgba(20,205,123,0.67)\"}",
"parentId" : ObjectId("5cee103ca01ad50f5c222983"),
"image" : "1559105656049.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:54:16.070Z"),
"createdAt" : ISODate("2019-05-29T04:54:16.070Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee10c1a01ad50f5c222985"),
"status" : "1",
"name" : "Drower 1",
"settings" : {
"zoom" : "5",
"positionX" : "470",
"positionY" : "70",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":3,\"points\":[{\"x\":21,\"y\":102},{\"x\":81,\"y\":104},{\"x\":79,\"y\":43},{\"x\":21,\"y\":43}],\"fill\":\"rgba(16,77,193,0.5)\"}",
"parentId" : ObjectId("5cee1078a01ad50f5c222984"),
"image" : "1559105729881.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:55:29.901Z"),
"createdAt" : ISODate("2019-05-29T04:55:29.901Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee110ea01ad50f5c222986"),
"status" : "1",
"name" : "Drawer 2",
"settings" : {
"zoom" : "5",
"positionX" : "484",
"positionY" : "103",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":1,\"coordinates\":{\"x\":23,\"y\":125,\"width\":58,\"height\":56},\"points\":[{\"x\":23,\"y\":125},{\"x\":81,\"y\":181}],\"fill\":\"rgba(117,37,109,0.74)\"}",
"parentId" : ObjectId("5cee1078a01ad50f5c222984"),
"image" : "1559105806551.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:56:46.574Z"),
"createdAt" : ISODate("2019-05-29T04:56:46.574Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee1148a01ad50f5c222987"),
"status" : "1",
"name" : "Drawer 3",
"settings" : {
"zoom" : "5",
"positionX" : "477",
"positionY" : "94",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":3,\"points\":[{\"x\":22,\"y\":205},{\"x\":20,\"y\":290},{\"x\":84,\"y\":288},{\"x\":85,\"y\":205}],\"fill\":\"rgba(164,108,54,0.57)\"}",
"parentId" : ObjectId("5cee1078a01ad50f5c222984"),
"image" : "1559105864947.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:57:44.972Z"),
"createdAt" : ISODate("2019-05-29T04:57:44.972Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee5e683b9f67a9f501f818"),
"status" : "1",
"name" : "Washroom",
"settings" : {
"zoom" : "5",
"positionX" : "477",
"positionY" : "94",
"width" : "498",
"height" : "498"
},
"area" : "{\"type\":3,\"points\":[{\"x\":22,\"y\":205},{\"x\":20,\"y\":290},{\"x\":84,\"y\":288},{\"x\":85,\"y\":205}],\"fill\":\"rgba(164,108,54,0.57)\"}",
"parentId" : ObjectId("5cee1002a01ad50f5c222982"),
"image" : "1559105864947.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:57:44.972Z"),
"createdAt" : ISODate("2019-05-29T04:57:44.972Z"),
"__v" : 0
},
{
"_id" : ObjectId("5cee5f593b9f67a9f501fa01"),
"status" : "1",
"name" : "Third Floor",
"settings" : {
"zoom" : "0",
"positionX" : "0",
"positionY" : "0",
"width" : "498",
"height" : "498"
},
"image" : "1559105538977123.jpg",
"businessId" : ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor" : [],
"updatedAt" : ISODate("2019-05-29T04:52:18.999Z"),
"createdAt" : ISODate("2019-05-29T04:52:18.999Z"),
"__v" : 0
}]
Expected result in JSON
[
{
"_id": "5cee1002a01ad50f5c222982",
"name": "Ground Floor"
},
{
"_id": "5cee103ca01ad50f5c222983",
"name": " Kitchen"
},
{
"_id": "5cee1078a01ad50f5c222984",
"name": " Cbot"
},
{
"_id": "5cee110ea01ad50f5c222986",
"name": " Drawer 2"
},
{
"_id": "5cee1148a01ad50f5c222987",
"name": " Drawer 3"
},
{
"_id": "5cee10c1a01ad50f5c222985",
"name": " Drower 1"
},
{
"_id": "5cee5e683b9f67a9f501f818",
"name": " Washroom"
},
{
"_id": "5cee5f593b9f67a9f501fa01",
"name": "Third Floor"
}
]
I do not think you should let mongodb take care of name formatting. So my solution is about finding how many spaces a certain name needs before, so that js can deal with formatting. This is the query:
db.collection.aggregate([
{
$graphLookup: {
from: "collection",
startWith: "$parentId",
connectFromField: "parentId",
connectToField: "_id",
as: "hierarchy"
}
},
{
$project: {
"_id": 1,
"name": 1,
"hierarchy_size": { $size: "$hierarchy" }
}
}
]);
With the $graphLookup, the db is building an in memory graph of edges between connectFromField and connectToField. From the graph you only need the depth of your hierarchy, so I computed hierarchy_size. This is the output:
/* 1 */
{
"_id" : ObjectId("5cee1002a01ad50f5c222982"),
"name" : "Ground Floor",
"hierarchy_size" : 0
}
/* 2 */
{
"_id" : ObjectId("5cee103ca01ad50f5c222983"),
"name" : "Kitchen",
"hierarchy_size" : 1
}
/* 3 */
{
"_id" : ObjectId("5cee1078a01ad50f5c222984"),
"name" : "Cbot",
"hierarchy_size" : 2
}
/* 4 */
{
"_id" : ObjectId("5cee10c1a01ad50f5c222985"),
"name" : "Drower 1",
"hierarchy_size" : 3
}
/* 5 */
{
"_id" : ObjectId("5cee110ea01ad50f5c222986"),
"name" : "Drawer 2",
"hierarchy_size" : 3
}
/* 6 */
{
"_id" : ObjectId("5cee1148a01ad50f5c222987"),
"name" : "Drawer 3",
"hierarchy_size" : 3
}
/* 7 */
{
"_id" : ObjectId("5cee5e683b9f67a9f501f818"),
"name" : "Washroom",
"hierarchy_size" : 1
}
/* 8 */
{
"_id" : ObjectId("5cee5f593b9f67a9f501fa01"),
"name" : "Third Floor",
"hierarchy_size" : 0
}
The only problem here might be query performances, but that depends on how much data you need to process. Also consider the memory limit.
Calculate All the number of agreements, contacts and the group by it on company name. Note. Agreements and Contacts are array of objects
This is a sample document of my data:
{
"_id" : ObjectId("57c7bd8f51666ac615bc837d"),
"ITBCompanyId" : 2296,
"updatedAt" : ISODate("2016-09-01T05:38:02.843Z"),
"createdAt" : ISODate("2016-09-01T05:33:03.604Z"),
"identifier" : "SOU10",
"name" : "Source One Rehabilitation",
"addressLine2" : null,
"city" : "Plano",
"state" : "TX",
"zip" : "75024",
"faxNumber" : "",
"territoryId" : "11",
"marketId" : null,
"accountNumber" : "Source One Rehabilitation",
"dateAcquired" : ISODate("2014-09-15T04:00:00.000Z"),
"parentCompany" : null,
"annualRevenue" : null,
"numberOfEmployees" : null,
"ownershipType" : null,
"deletedBy" : null,
"orgId" : "1",
"deletedAt" : null,
"_info" : {
"lastUpdated" : ISODate("2016-09-01T05:12:32.000Z"),
"updatedBy" : "LabTechInt"
},
"whois" : [],
"configuration" : [],
"contact" : [
{
"mobileGuid" : "6435d4c0-12fa-41d1-9db0-e4f9b1b4e7b2",
"presence" : null,
"gender" : null,
"title" : null,
"country" : null,
"zip" : "75024",
"state" : "TX",
"city" : "Plano",
"addressLine2" : null,
"lastName" : null,
"firstName" : "Dee Williams",
"id" : 821,
"_id" : ObjectId("57c7beba51666ac615bc8576"),
"communicationItems" : [],
"customFields" : null,
"relationship" : {
"name" : null,
"id" : 0
}
},
{
"id" : 829,
"firstName" : "Jesy",
"lastName" : "Leon",
"addressLine2" : null,
"city" : "Plano",
"state" : "TX",
"zip" : "75024",
"country" : null,
"title" : null,
"gender" : null,
"presence" : null,
"mobileGuid" : "2b0754c1-c256-4063-9cea-c40f9ca77084",
"_id" : ObjectId("57c7beba51666ac615bc857d"),
"communicationItems" : [
{
"communicationType" : "Email",
"defaultFlag" : true,
"extension" : null,
"type" : {
"_info" : null,
"name" : "Email",
"id" : 1
},
"id" : 45587
},
{
"communicationType" : "Phone",
"defaultFlag" : true,
"extension" : null,
"value" : "9728012190",
"type" : {
"_info" : null,
"name" : "Direct",
"id" : 2
},
"id" : 45590
}
],
"customFields" : null,
"company" : {
"id" : "19390",
"name" : "Source One Rehabilitation",
},
"relationship" : {
"id" : 0,
"name" : null
}
},
{
"id" : 850,
"firstName" : "Dr.",
"lastName" : "Gabriel",
"addressLine2" : null,
"city" : "Plano",
"state" : "TX",
"zip" : "75024",
"country" : null,
"title" : null,
"gender" : null,
"presence" : null,
"mobileGuid" : "8c833a31-369d-4499-87cb-b5598826e653",
"_id" : ObjectId("57c7beba51666ac615bc8592"),
"communicationItems" : [
{
"communicationType" : "Email",
"defaultFlag" : true,
"extension" : null,
"type" : {
"_info" : null,
"name" : "Email",
"id" : 1
},
"id" : 45627
},
{
"communicationType" : "Phone",
"defaultFlag" : true,
"extension" : null,
"value" : "9728012190",
"type" : {
"_info" : null,
"name" : "Direct",
"id" : 2
},
"id" : 45628
}
],
"customFields" : null,
"relationship" : {
"id" : 0,
"name" : null
}
}
],
"agreement" : [
{
"periodType" : null,
"billAmount" : "0",
"billTermsId" : 12,
"billOneTimeFlag" : false,
"billCycleId" : "2",
"expiredDays" : "0",
"coverAgreementExpense" : false,
"coverAgreementProduct" : false,
"coverAgreementTime" : true,
"oneTimeFlag" : false,
"applicationUnlimitedFlag" : true,
"applicationCycle" : "CalendarMonth",
"applicationLimit" : "0",
"applicationUnits" : "Hours",
"internalNotes" : "",
"workOrder" : "",
"slaId" : "2",
"reasonCancelled" : "",
"dateCancelled" : null,
"cancelledFlag" : false,
"noEndingDateFlag" : false,
"endDate" : "2016-01-31T05:00:00Z",
"startDate" : "2015-02-01T05:00:00Z",
"businessUnitId" : 2,
"locationId" : "11",
"customerPO" : "",
"parentAgreementId" : null,
"name" : "Complete Managed Services Agreement",
"id" : "109",
"_id" : ObjectId("57c7bd9051666ac615bc83e3"),
"_info" : {
"updatedBy" : "Ali ",
"lastUpdated" : ISODate("2016-05-12T20:55:21.000Z")
},
"workType" : {
"_info" : null,
"name" : "Remote",
"id" : "3"
},
"workRole" : {
"_info" : null,
"name" : "Support Engineer",
"id" : "5"
},
"contact" : {
"name" : "Heather B",
"id" : "539"
},
"agreementType" : {
"name" : "Complete Managed Services",
"id" : "19"
}
},
{
"id" : "121",
"name" : "Complete Managed Services: IMV",
"parentAgreementId" : null,
"customerPO" : "",
"locationId" : "11",
"businessUnitId" : 2,
"startDate" : "2016-03-01T05:00:00Z",
"endDate" : null,
"noEndingDateFlag" : true,
"cancelledFlag" : false,
"dateCancelled" : null,
"reasonCancelled" : "",
"slaId" : "2",
"workOrder" : "",
"internalNotes" : "",
"applicationUnits" : "Hours",
"applicationLimit" : "0",
"applicationCycle" : "CalendarMonth",
"applicationUnlimitedFlag" : true,
"oneTimeFlag" : false,
"coverAgreementTime" : true,
"coverAgreementProduct" : false,
"coverAgreementExpense" : false,
"expiredDays" : "0",
"billCycleId" : "2",
"billOneTimeFlag" : false,
"billTermsId" : 12,
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c7bd9051666ac615bc83fa"),
"_info" : {
"lastUpdated" : ISODate("2016-05-12T22:11:59.000Z"),
"updatedBy" : "Ali "
},
"workType" : {
"id" : "3",
"name" : "Remote",
"_info" : null
},
"workRole" : {
"id" : "5",
"name" : "Support Engineer",
"_info" : null
},
"contact" : {
"id" : "810",
"name" : "Jarrod Rogers"
},
"agreementType" : {
"id" : "19",
"name" : "Complete Managed Services"
}
},
{
"id" : "122",
"name" : "Complete Managed Servicess: FTW",
"parentAgreementId" : null,
"customerPO" : "",
"locationId" : "11",
"businessUnitId" : 2,
"startDate" : "2016-03-01T05:00:00Z",
"endDate" : null,
"noEndingDateFlag" : true,
"cancelledFlag" : false,
"dateCancelled" : null,
"reasonCancelled" : "",
"slaId" : "2",
"workOrder" : "",
"internalNotes" : "",
"applicationUnits" : "Hours",
"applicationLimit" : "0",
"applicationCycle" : "CalendarMonth",
"applicationUnlimitedFlag" : true,
"oneTimeFlag" : false,
"coverAgreementTime" : true,
"coverAgreementProduct" : false,
"coverAgreementExpense" : false,
"expiredDays" : "0",
"billCycleId" : "2",
"billOneTimeFlag" : false,
"billTermsId" : 12,
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c7bd9051666ac615bc83fd"),
"_info" : {
"lastUpdated" : ISODate("2016-05-12T22:14:29.000Z"),
"updatedBy" : "Ali "
},
"workType" : {
"id" : "3",
"name" : "Remote",
"_info" : null
},
"workRole" : {
"id" : "5",
"name" : "Support Engineer",
"_info" : null
},
"contact" : {
"id" : "810",
"name" : "Jarrod Rogers"
},
"agreementType" : {
"id" : "19",
"name" : "Complete Managed Services"
}
},
{
"id" : "123",
"name" : "Complete Managed Servicess: SC",
"parentAgreementId" : null,
"customerPO" : "",
"locationId" : "11",
"businessUnitId" : 2,
"startDate" : "2016-03-01T05:00:00Z",
"endDate" : null,
"noEndingDateFlag" : true,
"cancelledFlag" : false,
"dateCancelled" : null,
"reasonCancelled" : "",
"slaId" : "2",
"workOrder" : "",
"internalNotes" : "",
"applicationUnits" : "Hours",
"applicationLimit" : "0",
"applicationCycle" : "CalendarMonth",
"applicationUnlimitedFlag" : true,
"oneTimeFlag" : false,
"coverAgreementTime" : true,
"coverAgreementProduct" : false,
"coverAgreementExpense" : false,
"expiredDays" : "0",
"billCycleId" : "2",
"billOneTimeFlag" : false,
"billTermsId" : 12,
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c7bd9051666ac615bc83ff"),
"_info" : {
"lastUpdated" : ISODate("2016-05-12T22:13:59.000Z"),
"updatedBy" : "Ali "
},
"workType" : {
"id" : "3",
"name" : "Remote",
"_info" : null
},
"workRole" : {
"id" : "5",
"name" : "Support Engineer",
"_info" : null
},
"contact" : {
"id" : "810",
"name" : "Jarrod Rogers"
},
"agreementType" : {
"id" : "19",
"name" : "Complete Managed Services"
}
},
{
"id" : "124",
"name" : "Complete Managed Servicess: Psych",
"parentAgreementId" : null,
"customerPO" : "",
"locationId" : "11",
"businessUnitId" : 2,
"startDate" : "2016-03-01T05:00:00Z",
"endDate" : "2016-05-31T04:00:00Z",
"noEndingDateFlag" : false,
"cancelledFlag" : false,
"dateCancelled" : null,
"reasonCancelled" : "",
"slaId" : "2",
"workOrder" : "",
"internalNotes" : "",
"applicationUnits" : "Hours",
"applicationLimit" : "0",
"applicationCycle" : "CalendarMonth",
"applicationUnlimitedFlag" : true,
"oneTimeFlag" : false,
"coverAgreementTime" : true,
"coverAgreementProduct" : false,
"coverAgreementExpense" : false,
"expiredDays" : "0",
"billCycleId" : "2",
"billOneTimeFlag" : false,
"billTermsId" : 12,
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c7bd9051666ac615bc8402"),
"_info" : {
"lastUpdated" : ISODate("2016-06-01T16:48:03.000Z"),
"updatedBy" : "Ali "
},
"workType" : {
"id" : "3",
"name" : "Remote",
"_info" : null
},
"workRole" : {
"id" : "5",
"name" : "Support Engineer",
"_info" : null
},
"contact" : {
"id" : "810",
"name" : "Jarrod Rogers"
},
"agreementType" : {
"id" : "19",
"name" : "Complete Managed Services"
}
},
{
"id" : "125",
"name" : "Managed Services Agreement",
"parentAgreementId" : null,
"customerPO" : "",
"locationId" : "11",
"businessUnitId" : 2,
"startDate" : "2016-06-01T04:00:00Z",
"endDate" : null,
"noEndingDateFlag" : true,
"cancelledFlag" : false,
"dateCancelled" : null,
"reasonCancelled" : "",
"slaId" : null,
"workOrder" : "",
"internalNotes" : "",
"applicationUnits" : null,
"applicationLimit" : "0",
"applicationCycle" : null,
"applicationUnlimitedFlag" : false,
"oneTimeFlag" : false,
"coverAgreementTime" : false,
"coverAgreementProduct" : false,
"coverAgreementExpense" : false,
"expiredDays" : "0",
"billCycleId" : "2",
"billOneTimeFlag" : false,
"billTermsId" : 12,
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c7bd9051666ac615bc8404"),
"_info" : {
"lastUpdated" : ISODate("2016-06-01T16:17:45.000Z"),
"updatedBy" : "Ali "
},
"contact" : {
"id" : "810",
"name" : "Jarrod Rogers"
},
"agreementType" : {
"id" : "32",
"name" : "Agreement Template"
}
}
],
"companySite" : [
{
"id" : 1125,
"name" : "Main",
"addressLine1" : "5425 W. Spring Creek Pkwy #270",
"addressLine2" : null,
"city" : "Plano",
"state" : "TX",
"zip" : "75024",
"faxNumber" : null,
"taxCodeId" : null,
"expenseReimbursement" : null,
"primaryAddressFlag" : true,
"defaultShippingFlag" : false,
"defaultBillingFlag" : true,
"defaultMailingFlag" : false,
"_id" : ObjectId("57c7beb951666ac615bc84e5"),
"country" : {
"id" : 1,
"name" : "United States",
"_info" : null
},
"_info" : {
"lastUpdated" : ISODate("2016-09-01T05:12:28.000Z"),
"updatedBy" : "LabTechInt"
}
}
],
"status" : {
"id" : "1",
"name" : "Active"
},
"country" : {
"id" : 1,
"name" : "United States",
"_info" : null
},
"id" : "19390",
"__v" : 0
}
I want to count both the number of agreements and the number of contacts in a document, and group the data on company name and orgId.
This is my desired output:
{
"Company": "Multi-Metal Manufacturing",
"Organization": "1",
"AgreementCount" : 1,
"ContactCount" : 4
}
I tried this solution, but result is not as expected; it gives me a general count of all fields, but I want a specific count:
return Company.aggregate(
{"$unwind":"$agreement"},
{"$unwind":"$contact"},
{"$unwind":"$companySite"},
{ $group: {
_id: {
"Organization": "$orgId",
"Company": "$name"
},
"count": { $sum: 1 } } },
{"$project": {
"_id": 0,
"Company": "$_id.Company",
"Organization":"$_id.Organization",
"Count": "$count"
}
})
Assuming Companyname/orgId is unique, you can use $size which will get the size of your arrays to make this pretty simple:
[
{
$project:{
_id:false,
Company: "$name",
Organization: "$orgId",
AgreementCount: {
$size: {$ifNull: ["$agreement",[]]}
},
ContactCount: {
$size: {$ifNull: ["$contact",[]]}
}
}
}
]
If Companyname/orgId are not unique, then you can introduce a $group stage to sum the counts produced by $size:
[
{
$project:{
_id:false,
Company: "$name",
Organization: "$orgId",
AgreementCount: {
$size: {$ifNull: ["$agreement",[]]}
},
ContactCount: {
$size: {$ifNull: ["$contact",[]]}
}
}
},
{
$group: {
_id:{
Company: "$Company",
Organization: "$Organization"
},
AgreementCount: {$sum:"$AgreementCount"},
ContactCount: {$sum:"$ContactCount"}
}
},
{
$project:{
_id: false,
Company: "$_id.Company",
Organization: "$_id.Organization",
AgreementCount: true,
ContactCount: true
}
}
]
db.company.aggregate(
{$unwind:"$contact"},
{$unwind:"$agreement"},
{$group:
{_id: {"company":"$name","organization":"$orgId"},
"Contact":{$addToSet:"$contact._id"},
"Agreement":{$addToSet:"$agreement._id"}
}
},
{"$project":
{_id:0,
"Company":"$_id.company",
"Organization":"$_id.organization",
"AgreementCount":{$size:"$Agreement"},
"ContactCount":{$size:"$Contact"}
}
}).pretty();
return Company.aggregate([{
$project: {
ITBCompanyId: 1,
name: 1,
contact: {
$size: "$contact"
},
agreement: {
$size: "$agreement"
},
whoIs: {
$size: "$whois"
},
companySite: {
$size: "$companySite"
}
}
}])
I've got a project using the MEAN stack and inside the Mongo DB collection I've got a collection called 'services' with the following rows (a small subset):
{ "_id" : ObjectId("55af611de2be6d817d000001"), "client" : "55a8e5fa586f94752a000002", "collaborators" : null, "date" : ISODate("2015-07-22T09:23:41.917Z"), "latestUpdateDate" : ISODate("2015-07-22T09:23:41.917Z"), "backofficeRequested" : false, "description" : "Uma descrição qq", "wasSeen" : 0, "currentStatusId" : "0", "lastStatusId" : 4, "__v" : 2, "addresses" : [ ], "dates" : [ ], "estimateDuration" : 61, "estimatePrice" : "55", "notes" : [ ], "serviceDate" : ISODate("2015-07-23T10:07:00Z"), "totalPrice" : "600", "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55afa8662c1e98c80d2fd2ff"), "client" : "55a8e5fa586f94752a000002", "estimatePrice" : "12", "estimateDuration" : NumberLong(720), "description" : "12", "serviceDate" : ISODate("1212-12-12T12:48:45Z"), "lastStatusId" : null, "currentStatusId" : "0", "collaborators" : [ { "id" : "55acb6022c1e98d05f2fd2ff" } ], "dates" : [ ], "totalPrice" : "", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55afa9f62c1e98370e2fd2ff"), "client" : "55ae68d82c1e98ac782fd303", "estimatePrice" : "12", "estimateDuration" : NumberLong(720), "description" : "12", "serviceDate" : ISODate("1212-12-12T12:48:45Z"), "lastStatusId" : null, "currentStatusId" : "1", "collaborators" : [ { "id" : "55acb6022c1e98d05f2fd2ff" } ], "dates" : [ ], "totalPrice" : "500", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55afaa7e2c1e98bc0d2fd2ff"), "client" : "55a8e5fa586f94752a000002", "estimatePrice" : "12", "estimateDuration" : NumberLong(720), "description" : "12", "serviceDate" : ISODate("1212-12-12T12:48:45Z"), "lastStatusId" : null, "currentStatusId" : "0", "collaborators" : [ { "id" : "55acb6022c1e98d05f2fd2ff" } ], "dates" : [ ], "totalPrice" : "", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55afaf582c1e98d80d2fd303"), "client" : "55ae68d82c1e98ac782fd303", "estimatePrice" : "1", "estimateDuration" : NumberLong(60), "description" : "1", "serviceDate" : ISODate("1111-11-11T11:47:45Z"), "lastStatusId" : null, "currentStatusId" : "4", "collaborators" : [ { "id" : "55ae40772c1e98007a2fd2ff" } ], "dates" : [ ], "totalPrice" : "", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55afb8472c1e98370e2fd300"), "client" : "55a8e5fa586f94752a000002", "estimatePrice" : "1", "estimateDuration" : NumberLong(60), "description" : "1", "serviceDate" : ISODate("1111-11-11T11:47:45Z"), "lastStatusId" : null, "currentStatusId" : NumberLong(2), "collaborators" : [ { "id" : "55ae40772c1e98007a2fd2ff" } ], "dates" : [ ], "totalPrice" : "", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
{ "_id" : ObjectId("55aff2dc2c1e98ac112fd2ff"), "client" : "55a8e5fa586f94752a000002", "estimatePrice" : "1", "estimateDuration" : NumberLong(720), "description" : "1", "serviceDate" : ISODate("1989-12-12T12:12:00Z"), "lastStatusId" : null, "currentStatusId" : NumberLong(2), "collaborators" : [ { "id" : "55ae40772c1e98007a2fd2ff" } ], "dates" : [ ], "totalPrice" : "", "backofficeRequested" : NumberLong(0), "serviceInvoiced" : "No", "evaluation" : "", "positiveFeatures" : "", "negativeFeatures" : "" }
I want to get all the rows belonging to the client with the ID "55a8e5fa586f94752a000002".
It's pretty easy to do in the mongo Shell:
db.services.find({"client":"55a8e5fa586f94752a000002"})
But I am having a hard time inside Node.js because it either returns no services at all or it ends up returning just one service.
Here's what I'm using right now:
(...)
console.log(checkDatas[0]._id);
Service.find().where('client', checkDatas[0]._id)
.exec(function(err, services)
{
console.log("output: " + services);
(...)
And finally, here's the output:
**55a8e5fa586f94752a000002**
**output**: { _id: 55aff719af19b58913000001,
client: 55a8e5fa586f94752a000002,
__v: 1,
collaborators: [ { id: '55acb6022c1e98d05f2fd2ff' } ],
notes: [],
dates: [],
addresses: [],
date: Wed Jul 22 2015 22:03:37 GMT+0200 (CEST),
latestUpdateDate: Wed Jul 22 2015 22:03:37 GMT+0200 (CEST),
backofficeRequested: false,
totalPrice: null,
estimatePrice: null,
estimateDuration: null,
description: '',
serviceDate: null,
wasSeen: 0,
currentStatusId: 3,
lastStatusId: 1 }
It's as if I were using findOne but I'm not.
On top of that, yesterday I had a .sort() method also in that query and things worked fine after commenting it but today the problem's back.
Do MongoDB / Node have some sort of caching system I'm not aware of?
Thanks
EDIT:
Running
Service.find({'client': checkDatas[0]._id})
yields the same result
It looks like you're mixing ObjectId's and strings, which are two different things.
Your Mongoose query is looking for an ObjectId:
Service.find().where('client', checkDatas[0]._id)
Quick tip: you can distinguish both types in the output:
// ObjectId, because it doesn't have quotes around it
client: 55a8e5fa586f94752a000002
// String
collaborators: [ { id: '55acb6022c1e98d05f2fd2ff' } ]
Your MongoDB shell query is looking for a string:
db.services.find({"client":"55a8e5fa586f94752a000002"})
The subset you're posting shows only strings, but I think that your database may actually contain both types. You can check and see if this works better:
Service.find().or([
{ client : checkDatas[0]._id },
{ client : String(checkDatas[0]._id) }
])...
Obviously this isn't ideal, you should consider normalizing your database if both types are mixed.
EDIT: the or query probably won't work when using Mongoose, since it will cast both clauses to the type defined in the schema. You can still check from the Mongo shell:
db.services.find({ $or : [
{ client : "55a8e5fa586f94752a000002" },
{ client : ObjectId("55a8e5fa586f94752a000002") }
]})
I have set of baskets stored in mongodb like:
/* 47 */
{
"_id" : ObjectId("535ff14c2e441acf44708ec7"),
"tip" : "0",
"basketTransactionCash" : "2204",
"basketTransactionCard" : "0",
"completed" : ISODate("2014-04-07T14:35:17.000Z"),
"consumerId" : null,
"storeId" : 1,
"basketId" : 210048,
"basketProduct" : [
{
"_id" : ObjectId("535feffa2e441acf446facb7"),
"name" : "Vanilla Spice Hot Chocolate",
"productId" : 23,
"basketProductInstanceId" : 838392,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "633",
"vatPercentage" : "0.2"
}
],
"created" : ISODate("2014-04-07T14:35:42.000Z"),
"__v" : 0
}
/* 48 */
{
"_id" : ObjectId("535ff14c2e441acf44708ede"),
"tip" : "0",
"basketTransactionCash" : "230",
"basketTransactionCard" : "0",
"completed" : ISODate("2014-04-07T14:41:51.000Z"),
"consumerId" : 1,
"storeId" : 1,
"basketId" : 210072,
"basketProduct" : [
{
"_id" : ObjectId("535feffa2e441acf446facf3"),
"name" : "Melon",
"productId" : 4544,
"basketProductInstanceId" : 838430,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "200",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffa2e441acf446facf4"),
"name" : "30p",
"productId" : 8496,
"basketProductInstanceId" : 838431,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "30",
"vatPercentage" : "0"
}
],
"created" : ISODate("2014-04-07T14:42:16.000Z"),
"__v" : 0
}
/* 49 */
{
"_id" : ObjectId("535ff14c2e441acf44708ee2"),
"tip" : "0",
"basketTransactionCash" : "2204",
"basketTransactionCard" : "0",
"completed" : ISODate("2014-04-07T14:41:54.000Z"),
"consumerId" : 2,
"storeId" : 1,
"basketId" : 210076,
"basketProduct" : [
{
"_id" : ObjectId("535feffb2e441acf446fad02"),
"name" : "Creamy Natural Yoghurt",
"productId" : 69,
"basketProductInstanceId" : 839800,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "911.7",
"vatPercentage" : "0.2"
},
{
"_id" : ObjectId("535feffb2e441acf446fad03"),
"name" : "Melon",
"productId" : 4544,
"basketProductInstanceId" : 839801,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "200",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffb2e441acf446fad04"),
"name" : "30p",
"productId" : 8496,
"basketProductInstanceId" : 839802,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "30",
"vatPercentage" : "0"
}
],
"created" : ISODate("2014-04-07T14:43:00.000Z"),
"__v" : 0
}
Could I have this grouped by completed by hourly? So the end result should be something similar to the below
{
"totalTip" : "0",
"basketTransactionCashTotal" : "4638",
"basketTransactionCardTotal" : "0",
"completed" : "2014-04-07 14",
"consumerIds" : [null, 1, 2],
"storeId" : 1,
"basketIds" : [210048, 210072, 210076]
"basketProduct" : [
{
"_id" : ObjectId("535feffa2e441acf446facf3"),
"name" : "Melon",
"productId" : 4544,
"basketProductInstanceId" : 838430,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "200",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffa2e441acf446facf4"),
"name" : "30p",
"productId" : 8496,
"basketProductInstanceId" : 838431,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "30",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffb2e441acf446fad02"),
"name" : "Creamy Natural Yoghurt",
"productId" : 69,
"basketProductInstanceId" : 839800,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "911.7",
"vatPercentage" : "0.2"
},
{
"_id" : ObjectId("535feffb2e441acf446fad03"),
"name" : "Melon",
"productId" : 4544,
"basketProductInstanceId" : 839801,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "200",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffb2e441acf446fad04"),
"name" : "30p",
"productId" : 8496,
"basketProductInstanceId" : 839802,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "30",
"vatPercentage" : "0"
},
{
"_id" : ObjectId("535feffa2e441acf446facb7"),
"name" : "Vanilla Spice Hot Chocolate",
"productId" : 23,
"basketProductInstanceId" : 838392,
"quantity" : 1,
"productModifiedPrice" : null,
"productInstancePrice" : "633",
"vatPercentage" : "0.2"
}
]
}
Could anyone help me understand this for mongoose in nodejs please?
First of all, the fields tip, basketTransactionCash and basketTransactionCard need to be converted to numeric type for you to perform any arithmetic operations. You can look at this question for an approach to update all documents with the right data type.
Once the data type is taken care of, you can use the aggregation framework to get close to what you want. The date aggregation operators provide a way to group by the hour. Sample query is below:
db.collection.aggregate([
{
"$group": {
"_id": {
"year": {"$year": "$completed"},
"month": {"$month": "$completed"},
"day": {"$dayOfMonth": "$completed"},
"hour": {"$hour": "$completed"}
},
"totalTip": {
"$sum": "$tip"
},
"basketTransactionCashTotal": {
"$sum": "$basketTransactionCash"
},
"basketTransactionCardTotal": {
"$sum": "$basketTransactionCard"
},
"consumerIds": {
"$push": "$consumerId"
},
"storeId": {
"$addToSet": "$storeId"
},
"basketIds": {
"$push": "$basketId"
},
"basketProducts": {
"$push": "$basketProduct"
}
}
}
])
I would suggest you to read up on aggregation and play around with it a little bit as it's a quite powerful tool.
NOTE: Unless the data types are updated, you'll get 0 for totalTip, basketTransactionCashTotal and basketTransactionCardTotal