0

My document structure looks like this:

{
   "_id" : ObjectId("5aeeda07f3a664c55e830a08"),
   "profileId" : ObjectId("5ad84c8c0e71892058b6a543"),
   "list" : [ 
      {           
        "content" : "answered your post",
        "createdBy" : ObjectId("5ad84c8c0e71892058b6a540")
      }, 
      {           
        "content" : "answered your post",
        "createdBy" : ObjectId("5ad84c8c0e71892058b6a540")
      }, 
      {
        "content" : "answered your post",
        "createdBy" : ObjectId("5ad84c8c0e71892058b6a540")
      }, 
    ],   
}

I want to count array of list field. And apply condition before slicing that

if the list<=10 then slice all the elements of list

else 10 elements.

P.S I used this query but is returning null.

db.getCollection('post').aggregate([
 {
  $match:{
       profileId:ObjectId("5ada84c8c0e718s9258b6a543")}
 },
 {$project:{notifs:{$size:"$list"}}},    
 {$project:{notifications:
            {$cond:[
                {$gte:["$notifs",10]},
                {$slice:["$list",10]},
                {$slice:["$list","$notifs"]}
            ]}
          }}
])
2
  • 1
    Try using $addFields instead of the first $project. Commented May 9, 2018 at 10:57
  • thanks @dnickless it worked. Commented May 9, 2018 at 11:04

1 Answer 1

2

Your first $project stage effectively wipes out all result fields but the one(s) that it explicitly projects (only notifs in your case). That's why the second $project stage cannot $slice the list field anymore (it has been removed by the first $project stage).

Also, I think your $cond/$slice combination can be more elegantly expressed using the $min operator. So there's at least the following two fixes for your problem:

Using $addFields:

db.getCollection('post').aggregate([
  { $match: { profileId: ObjectId("5ad84c8c0e71892058b6a543") } },
  { $addFields: { notifs: { $size: "$list" } } },    
  { $project: {
    notifications: {
      $slice: [ "$list", { $min: [ "$notifs", 10 ] } ]
    }
  }}
])

Using a calculation inside the $project - this avoids a stage so should be preferable.

db.getCollection('post').aggregate([
  { $match: { profileId: ObjectId("5ad84c8c0e71892058b6a543") } },
  { $project: {
    notifications: {
      $slice: [ "$list", { $min: [ { $size: "$list" }, 10 ] } ]
    }
  }}
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.