Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb aggregate $push with $cond and $each

I'm trying to use $cond to conditionally $push multiple integers onto a numbers array during an aggregate $group without any success. Here is my code:

Item.aggregate(
    [
      {
        $group: {
          _id: "$_id",
          numbers: {
            $push: {
              $cond: { 
                if: { $gt: [ "$price.percent", 70 ] }, 
                then: { $each: [10,25,50,70] },
                else: null,
              }
            }
          }
        }
      },
    ]
  )
  ...

Is Mongo DB just not set up for this right now, or am I looking at this all wrong?

like image 488
user1828780 Avatar asked Feb 18 '16 05:02

user1828780


People also ask

What are the differences between using aggregate () and find () in MongoDB?

With aggregate + $match, you get a big monolithic BSON containing all matching documents. With find, you get a cursor to all matching documents. Then you can get each document one by one.

Which is faster aggregate or find in MongoDB?

The aggregation query takes ~80ms while the find query takes 0 or 1ms.

Which aggregate method is preferred for use by MongoDB?

The pipeline provides efficient data aggregation using native operations within MongoDB, and is the preferred method for data aggregation in MongoDB. The aggregation pipeline can operate on a sharded collection. The aggregation pipeline can use indexes to improve its performance during some of its stages.


2 Answers

Please try it without $each as below

Item.aggregate(
    [{
        $group: {
          _id: "$_id",
          numbers: {
            $push: {
              $cond: { 
                if: { $gt: [ "$price.percent", 70 ] }, 
                then: [10,25,50,70] ,
                else: null,
              }
            }
          }
        }
      }]);
like image 59
zangw Avatar answered Nov 01 '22 11:11

zangw


Provided answers will work but they'll add null to the array whenever else block gets executed & at the end you need to filter out the null values from the actual array (numbers) which is an additional step to do!

You can use $$REMOVE to conditionally exclude fields in MongoDB's $project.

Item.aggregate(
    [{
        $group: {
            _id: "$_id",
            numbers: { $push: { $cond: [{ $gt: ["$price.percent", 70] }, [10, 25, 50, 70], '$$REMOVE'] } } // With $$REMOVE nothing happens on else
        }
    }]);

REF: $cond

like image 29
whoami - fakeFaceTrueSoul Avatar answered Nov 01 '22 12:11

whoami - fakeFaceTrueSoul