Sarkis Arutiunian Sarkis Arutiunian - 3 months ago 7
Node.js Question

Return array of first matches by field value

For example I have collection with following type:

[
{ batch: false, type: '' },
{ batch: false, type: '' },
{ batch: true, type: '123' },
{ batch: true, type: '123' },
{ batch: true, type: '123' },
{ batch: true, type: '234' },
{ batch: true, type: '234' },
{ batch: true, type: '234' },
{ batch: true, type: '234' },
{ batch: true, type: '567' },
{ batch: true, type: '567' }
]


so question is, how to return array of objects which have
{batch: false}
and if
{batch: true}
return only first object with same
{type}
field, basically I want get following response:

[
{ batch: false, type: '' },
{ batch: false, type: '' },
{ batch: true, type: '123' },
{ batch: true, type: '234' },
{ batch: true, type: '567' }
]

Answer

Try the following aggregation pipeline

db.getCollection('yourCollection').aggregate([
    {
        $group: {
            _id: {
                k1: {
                    $cond: {
                        if: "$batch",
                        then: null,
                        else: "$_id"
                    }
                },
                k2: "$type"
            },
            batch: { $first: "$batch" },
            type: { $first: "$type" }
        }
    },
    {
        $project: {
            _id: 0,
            batch: 1,
            type: 1
        }
    }
])

which results in

/* 1 */
{
    "batch" : false,
    "type" : ""
}

/* 2 */
{
    "batch" : false,
    "type" : ""
}

/* 3 */
{
    "batch" : true,
    "type" : "123"
}

/* 4 */
{
    "batch" : true,
    "type" : "567"
}

/* 5 */
{
    "batch" : true,
    "type" : "234"
}
Comments