Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoDB is there any way for aggregate $gte to not show the false data

https://docs.mongodb.com/manual/reference/operator/aggregation/gte/

As you can see in the above mongo db documentation, $gte returns the data which is false too.

Example json data:

{ "_id" : 1, "item" : "abc1", description: "product 1", qty: 300 }
{ "_id" : 2, "item" : "abc2", description: "product 2", qty: 200 }
{ "_id" : 3, "item" : "xyz1", description: "product 3", qty: 250 }
{ "_id" : 4, "item" : "VWZ1", description: "product 4", qty: 300 }
{ "_id" : 5, "item" : "VWZ2", description: "product 5", qty: 180 }

Query for getting the data where qty is greater than 250:

db.inventory.aggregate(
   [
     {
       $project:
          {
            item: 1,
            qty: 1,
            qtyGte250: { $gte: [ "$qty", 250 ] },
            _id: 0
          }
     }
   ]
)

Output:

{ "item" : "abc1", "qty" : 300, "qtyGte250" : true }
{ "item" : "abc2", "qty" : 200, "qtyGte250" : false }
{ "item" : "xyz1", "qty" : 250, "qtyGte250" : true }
{ "item" : "VWZ1", "qty" : 300, "qtyGte250" : true }
{ "item" : "VWZ2", "qty" : 180, "qtyGte250" : false }

Problem: Well I want data where qty > 250, but mongo db shows all data, and thus when records are so high in number the site becomes so slow.

I am using ruby on rails with mongoid, and I have some query where I need to use group by clause, so I have to aggregate, but this is return all data. My original Query:

data = SomeModel.collection.aggregate([
      {"$project" => {
        "dayOfMonth" => {"$dayOfMonth" => "$created_time"},
        "month" => {"$month" => "$created_time"},
        "year" => {"$year" => "$created_time"},
        "date_check_gte" => {"$gte" => ["$created_time",start_time]},
        "date_check_lte" => {"$lte" => ["$created_time",end_time]},
      }},
      {"$group" => {
        "_id" => { "dayOfMonth" => "$dayOfMonth", "month" => "$month", "year" => "$year"},
        "Total" => {"$sum" => 1},
        "check_one" => {"$first" => "$date_check_gte"},
        "check_two" => {"$first" => "$date_check_lte"}
      }},
      {"$sort" => {
        "Total" => 1
      }}
    ])

Groups perfectly but returns all data despite the use of gte and lte. Is there anything that can be done so that false data don't show up ?

like image 411
user1735921 Avatar asked Feb 06 '23 05:02

user1735921


2 Answers

The "query" for getting data where qty is greater than 250 involves the $match pipeline operator which filters the documents to pass only the documents that match the specified condition(s) to the next pipeline stage, and not the $project pipeline as you are currently doing:

db.inventory.aggregate([
    { "$match": { "qty": { "$gte": 250 } } }   
)

or using the same $project pipeline (although not necessary since using just a single $match pipeline as above would suffice):

db.inventory.aggregate([
    {
        "$project": {
            "item": 1,
            "qty": 1,
            "qtyGte250": { "$gte": [ "$qty", 250 ] },
            "_id": 0
        }
    },
    { "$match": { "qtyGte250": true } }   
])
like image 113
chridam Avatar answered Feb 08 '23 17:02

chridam


Did you try using $match in the pipeline to filter document whose qty > 250?

Ex:

db.inventory.aggregate(
   [ {$match: {qty: {$gt: 250}}},
     {
       $project:
          {
            item: 1,
            qty: 1,
            _id: 0
          }
     }
   ]
)
like image 43
Madhusudana Reddy Sunnapu Avatar answered Feb 08 '23 17:02

Madhusudana Reddy Sunnapu