Noman Maqsood Noman Maqsood - 2 months ago 10
Node.js Question

Search in subdocument

Hello I want to get all the contacts with syncFlag true in contact object.

I tried this solution but only returns only one sub document

and I also tried this solution it returns all the documents either they are matched or not

How to find document and single subdocument matching given criterias in MongoDB collection

Here is the sample document

{
"_id" : ObjectId("57ce7d6c7387d533bfa2d45c"),
"ITBCompanyId" : 2608,
"updatedAt" : ISODate("2016-09-06T12:19:35.972Z"),
"createdAt" : ISODate("2016-09-06T08:25:16.325Z"),
"name" : "This is test",
"identifier" : "THDNOM2",
"addressLine1" : "Valencia Lahore",
"syncFlag" : true,
"orgId" : "1",
"deletedAt" : null,
"whois" : [
{
"test" : "noman"
}
],
"configuration" : [
{
"test" : "noman"
}
],
"contact" : [
{
"firstName" : "Active",
"_id" : ObjectId("57ceb04811f005420b7ed54a"),
"syncFlag" : false,
"communicationItems" : [],
"customFields" : []
},
{
"firstName" : "Active",
"_id" : ObjectId("57ceb04811f005420b7ed54b"),
"syncFlag" : false,
"communicationItems" : [],
"customFields" : []
},
{
"firstName" : "Active",
"_id" : ObjectId("57ceb44b5f8b534bc312aacd"),
"syncFlag" : true,
"communicationItems" : [],
"customFields" : []
},
{
"firstName" : "Active",
"_id" : ObjectId("57ceb457f141fd4c1c98a748"),
"syncFlag" : true,
"communicationItems" : [],
"customFields" : []
}
],
"agreement" : [
{
"test" : "noman"
}
],
"companySite" : [
{
"test" : "noman"
}
],
"companyNote" : [
{
"test" : "noman"
}
],
"type" : {
"name" : "Client"
},
"status" : {
"name" : "Active"
},
"id" : "19493",
"__v" : 0,
"_info" : {
"updatedBy" : "Omer",
"lastUpdated" : ISODate("2016-09-06T11:52:07.000Z")
}
}


Expected Output:

ITBCompanyId: 1,
contact: [{
"firstName" : "Active",
"_id" : ObjectId("57ceb04811f005420b7ed54b"),
"syncFlag" : true,
"communicationItems" : [],
"customFields" : []

}]

Answer

Try this. You should get the document as required. Below I have used an aggregate query to format the mongodb response as required. For more information regarding mongodb aggregate, you can refer this. I reffered this stack overflow post for forming this query.

db.companies.aggregate(
    { $match: {"contact.syncFlag": true }},
    { $unwind: '$contact'},
    { $match: {"contact.syncFlag": true }},
    { $group: { 
            _id: '$_id',  
            contact: {$push: '$contact'},
    }
});

If you want all the other fields included in the document. You can try this.

db.companies.aggregate(
    { $match: {"contact.syncFlag": true }},
    { $unwind: '$contact'},
    { $match: {"contact.syncFlag": true }},
    { $group: { 
        _id: '$_id', 
        ITBCompanyId: {$first: '$ITBCompanyId'}, 
        updatedAt: {$first: '$updatedAt'}, 
        createdAt: {$first: '$createdAt'}, 
        name: {$first: '$name'}, 
        identifier: {$first: '$identifier'}, 
        addressLine1: {$first: '$addressLine1'}, 
        syncFlag: {$first: '$syncFlag'}, 
        orgId: {$first: '$orgId'}, 
        deletedAt: {$first: '$deletedAt'}, 
        whois: {$first: '$whois'}, 
        configuration: {$first: '$configuration'}, 
        contact: {$push: '$contact'},
        agreement: {$first: '$agreement'},
        companySite: {$first: '$companySite'},
        companyNote: {$first: '$companyNote'},
        type: {$first: '$type'},
        status: {$first: '$status'},
        id: {$first: '$id'},
        _info: {$first: '$_info'},
    }
});
Comments