Search code examples
mongodbaggregation-frameworkaggregate

MongoDB - How to filter and get last data in array field


How to make a filter and then slice some array in MongoDB?

I've tried with this aggregate but got an error. I think the problem is in the project stage. The project stage can't accept two expressions. Is there another way?

 [
  {
    $match: {
      _id: ObjectId("65a739bc29c608fd90b65038"),
    },
  },
  {
    $project: {
      date: 1,
      serviceScheduleId: 1,
      serviceId: 1,
      branchOfficeId: 1,
      queue: {
        $filter: {
          input: "$queue",
          cond: {
            $and: [
              {
                $eq: [
                  "$$this.user.status",
                  "waiting",
                ],
              },

            ],
          },
        },
        $slice:{"$queue",1]
      },
    },
  },
]

Solution

  • You should either need an additional $set/$project stage for setting the queue field with the $slice operator.

    {
      $project: {
        ...,
        queue: {
          $filter: {
            input: "$queue",
            cond: {
              $and: [
                {
                  $eq: [
                    "$$this.user.status",
                    "waiting"
                  ]
                }
              ]
            }
          }
        }
      }
    },
    {
      $set: {
        queue: {
          $slice: ["$queue", 1]
        }
      }
    }
    

    Or place the whole $filter operator as the first argument of the $slice operator.

    {
      $project: {
        ...
        queue: {
          $slice: [
            {
              $filter: {
                input: "$queue",
                cond: {
                  $and: [
                    {
                      $eq: [
                        "$$this.user.status",
                        "waiting"
                      ]
                    }
                  ]
                }
              }
            },
            1
          ]
        }
      }
    }
    

    For getting the last element of the array, use the $last operator and the structure should be:

    queue: {
      $last: /* $filter operator */
    }