Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to $slice a $filter result in MongoDB?

I have a collection with the following format:

{
    "_id": 123,
    "items": [{
        "status" : "inactive",
        "created" : ISODate("2016-03-16T10:39:28.321Z")
    },
    {
        "status" : "active",
        "created" : ISODate("2016-03-16T10:39:28.321Z")
    },
    {
        "status" : "active",
        "created" : ISODate("2016-03-16T10:39:28.321Z")
    }
    ],
    "status" : "active"
}

I want to query on status field of items such that the object with status as 'active' is only returned in the array and also only the last 2 are returned in the query.

At present I am using $filter for this operation, but I am not able to use $slice along with $filter(which I think is needed for what I desire). The following is how my query looks right now:

db.collection('collection').aggregate([
{$match: {'status': 'active'}},
{
    $project: {
        'items': {
            $filter: {
                input: '$items', 
                as: 'item', 
                cond: {$eq: ['$$item.status', 'active']
            }
        }
    }
}]);

What I am getting right now is correct result, its just that it returns all the objects in the items field and I just want the last 2 objects.

like image 262
HVT7 Avatar asked Dec 07 '22 23:12

HVT7


1 Answers

To get the last two elements use the $slice operator and set the position operand to -2. Of course the first operand to the slice operator is the $filter expression which resolves to an array.

db.collection.aggregate([
    { "$match": { "items.status": "active" } }, 
    { "$project": { 
        "items": { 
            "$slice": [ 
                { "$filter": { 
                    "input": "$items",
                    "as": "item", 
                    "cond": { "$eq": [ "$$item.status", "active" ] } 
                }}, 
                -2 
            ] 
        } 
    }}
])
like image 66
styvane Avatar answered Dec 21 '22 13:12

styvane