Mongodb Count on multiple sub arrays - node.js

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"
}
}
}])

Related

How to update my address throug _id in myAddresses mongodb nodejs?

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
}
})

"How to get 'parent to child' relation with mongodb aggregation"

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.

Mongodb Count multiple subobjects and group by

Hello This query is running fine for me I want to add other arrays as well like contact and I want separate count for them. If I add contact it add the result in count P.S : I used array name with $sum it start showing me zero 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"
}
})
expected output
"Company": "Multi-Metal Manufacturing",
"Organization": "1",
"AgreementCount": 1,
"ContactCount" : 4
"ABC Count": 5
Sample Document is :
{
"_id" : ObjectId("57c6a97a90c933a2d54117dc"),
"ITBCompanyId" : 1034,
"updatedAt" : ISODate("2016-08-31T12:47:03.679Z"),
"createdAt" : ISODate("2016-08-31T09:55:06.217Z"),
"identifier" : "INL10",
"name" : "Inline Data Systems",
"addressLine1" : "7 Park Place",
"addressLine2" : "Ste D",
"city" : "Swansea",
"orgId" : "1",
"deletedAt" : null,
"_info" : {
"lastUpdated" : ISODate("2016-02-10T21:22:15.000Z"),
"updatedBy" : "Clarissa"
},
"whois" : [],
"configuration" : [],
"contact" : [
{
"email" : "justin#inlinedatasystems.com",
"mobileGuid" : "d8852942-8f5a-406f-a646-a5f8697f7885",
"presence" : null,
"gender" : null,
"title" : null,
"country" : null,
"zip" : null,
"state" : null,
"city" : null,
"addressLine2" : null,
"addressLine1" : null,
"lastName" : "Wilkerson",
"firstName" : "Justin",
"id" : 191,
"_id" : ObjectId("57c6abdfb966968130b1671c"),
"communicationItems" : [],
"customFields" : null,
"company" : {
"name" : "Inline Data Systems",
"id" : "19331"
},
"relationship" : {
"name" : null,
"id" : 0
}
}
],
"agreement" : [
{
"periodType" : null,
"billAmount" : "0",
"billTermsId" : 12,
"billOneTimeFlag" : false,
"billCycleId" : "2",
"expiredDays" : "0"
},
{
"id" : "40",
"name" : "Managed Hosted Server Agreement",
"billAmount" : "0",
"periodType" : null,
"_id" : ObjectId("57c6ab96b966968130b16616"),
"_info" : {
"lastUpdated" : ISODate("2014-10-03T14:25:42.000Z"),
"updatedBy" : "ali "
},
"contact" : {
"id" : "191",
"name" : "Justin Wilkerson"
},
"agreementType" : {
"id" : "33",
"name" : "HDCloud - Hosted Server"
}
},
{
"id" : "41",
"name" : "Managed Backup Agreement",
"parentAgreementId" : "42",
"customerPO" : ""
}
],
"companySite" : [
{
"id" : 1037,
"name" : "Main",
"city" : "Swansea",
"state" : "IL",
"zip" : "62226",
}
]

Mongo/Mongoose - Find by partial document

I have a collection of properties that all have addresses.
"address" : {
"street" : "5 Orange Drive",
"city" : "Orlando",
"state" : {
"abbreviation" : "FL",
"name" : "Florida"
},
"zip" : "32822",
"geo" : {
"lat" : 28.519,
"lng" : -81.304
}
},
"address" : {
"street" : "16 Main Street",
"city" : "Tallahassee",
"state" : {
"abbreviation" : "FL",
"name" : "Florida"
},
"zip" : "32823",
"geo" : {
"lat" : 28.529,
"lng" : -81.314
}
},
"address" : {
"street" : "125 Oak Drive",
"city" : "Salem",
"state" : {
"abbreviation" : "MA",
"name" : "Massachusetts"
},
"zip" : "02108",
"geo" : {
"lat" : 24.519,
"lng" : -83.304
}
},
"address" : {
"street" : "96 Jones Way",
"city" : "Springfield",
"state" : {
"abbreviation" : "MA",
"name" : "Massachusetts"
},
"zip" : "01020",
"geo" : {
"lat" : 28.519,
"lng" : -84.304
}
},
"address" : {
"street" : "100 Sumner Ave",
"city" : "Springfield",
"state" : {
"abbreviation" : "IL",
"name" : "Illinois"
},
"zip" : "32822",
"geo" : {
"lat" : 22.519,
"lng" : -71.304
}
},
"address" : {
"street" : "40 Roger Ave",
"city" : "Salem",
"state" : {
"abbreviation" : "AL",
"name" : "Alabama"
},
"zip" : "32822",
"geo" : {
"lat" : 22.519,
"lng" : -71.304
}
}
I have an earlier query that returns an array of addresses such as:
[
{
name: 'Massachusetts - Salem',
city: 'Salem',
_id: 53784206cd73fbae193b62d5,
state: [Object]
}, {
name: 'Illinois - Springfield',
city: 'Springfield',
_id: 5376fa92bde0e0ea047e9abd,
state: [Object]
}
]
I would like to use the output of the above array to search the collection of properties by address.
Such as, I would like to search for all properties where the address contains a 'city of Springfield and a state of Illinois' and 'city of Salem and a state of Massachusetts'.
I was originally trying to do this using $in with some $and's mixed in but I wasn't sure if it was possible.
You could try using the $or operator on an array that contains query conditions derived from the other input array. For example, with the sample properties collection:
db.properties.insert([
{
"address" : {
"street" : "5 Orange Drive",
"city" : "Orlando",
"state" : {
"abbreviation" : "FL",
"name" : "Florida"
},
"zip" : "32822",
"geo" : {
"lat" : 28.519,
"lng" : -81.304
}
}
},
{
"address" : {
"street" : "16 Main Street",
"city" : "Tallahassee",
"state" : {
"abbreviation" : "FL",
"name" : "Florida"
},
"zip" : "32823",
"geo" : {
"lat" : 28.529,
"lng" : -81.314
}
}
},
{
"address" : {
"street" : "125 Oak Drive",
"city" : "Salem",
"state" : {
"abbreviation" : "MA",
"name" : "Massachusetts"
},
"zip" : "02108",
"geo" : {
"lat" : 24.519,
"lng" : -83.304
}
}
},
{
"address" : {
"street" : "96 Jones Way",
"city" : "Springfield",
"state" : {
"abbreviation" : "MA",
"name" : "Massachusetts"
},
"zip" : "01020",
"geo" : {
"lat" : 28.519,
"lng" : -84.304
}
}
},
{
"address" : {
"street" : "100 Sumner Ave",
"city" : "Springfield",
"state" : {
"abbreviation" : "IL",
"name" : "Illinois"
},
"zip" : "32822",
"geo" : {
"lat" : 22.519,
"lng" : -71.304
}
}
},
{
"address" : {
"street" : "40 Roger Ave",
"city" : "Salem",
"state" : {
"abbreviation" : "AL",
"name" : "Alabama"
},
"zip" : "32822",
"geo" : {
"lat" : 22.519,
"lng" : -71.304
}
}
}
])
The following query would give the desired result:
var res = [
{
"name": 'Massachusetts - Salem',
"city": 'Salem',
"_id": "53784206cd73fbae193b62d5",
"state": [{"name": "Massachusetts", "abbreviation": "MA"}]
}, {
"name": 'Illinois - Springfield',
"city": 'Springfield',
"_id": "5376fa92bde0e0ea047e9abd",
"state": [{"name": "Illinois", "abbreviation": "IL"}]
}
];
var condition = res.map(function (item){
return {
"address.city": item.city,
"address.state.name": item.state[0].name
}
});
db.properties.find({"$or": condition });
Sample Output
/* 0 */
{
"_id" : ObjectId("557848b43cab061ff5c618b7"),
"address" : {
"street" : "125 Oak Drive",
"city" : "Salem",
"state" : {
"abbreviation" : "MA",
"name" : "Massachusetts"
},
"zip" : "02108",
"geo" : {
"lat" : 24.519,
"lng" : -83.304
}
}
}
/* 1 */
{
"_id" : ObjectId("557848b43cab061ff5c618b9"),
"address" : {
"street" : "100 Sumner Ave",
"city" : "Springfield",
"state" : {
"abbreviation" : "IL",
"name" : "Illinois"
},
"zip" : "32822",
"geo" : {
"lat" : 22.519,
"lng" : -71.304
}
}
}

Mongodb Aggregation and Group By query

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

Resources