how to compare two fields in a document in pipeline aggregation (mongoDB)

Mohammad_Hosseini picture Mohammad_Hosseini · Dec 29, 2016 · Viewed 17.1k times · Source

I have a document like below :

{
  "user_id": NumberLong(1),
  "updated_at": ISODate("2016-11-17T09:35:56.200Z"),
  "created_at": ISODate("2016-11-17T09:35:07.981Z"),
  "banners": {
    "normal_x970h90": "/images/banners/4/582d79cb3aef567d64621be9/photo-1440700265116-fe3f91810d72.jpg",
    "normal_x468h60": "/images/banners/4/582d79cb3aef567d64621be9/photo-1433354359170-23a4ae7338c6.jpg",
    "normal_x120h600": "/images/banners/4/582d79cb3aef567d64621be9/photo-1452570053594-1b985d6ea890.jpg"
  },
  "name": "jghjghjghj",
  "budget": "2000",
  "plan": null,
  "daily_budget": "232323",
  "daily_budget_auto": "",
  "href": "qls2.ir",
  "targets": {
    "cats": [
      "fun",
      "news"
    ],
    "region": "inIran",
    "iran_states": null,
    "os": "all",
    "gold_network": true,
    "dont_show_between_1_n_8": true
  },
  "payment": {
    "bank": "mellat",
    "tax": "add"
  },
  "click_cost": "102000",
  "status": null
}

I want to check if budget is lower than click_cost while I'm checking some other parameters in my query :

db.bcamp.aggregate(
    [
        {
            $match:{
                $and: [ 
                    {"targets.cats":{
                        "$in" : ["all"]
                        }
                    },

                    {"banners.normal_x970h90":{
                        "$exists":true
                        }
                    },

                    {"href": {
                        $nin: ["qls.ir"]
                        }
                    }
                ]
            }
        }
    ]).pretty();

I have tried compare method like :

db.bcamp.aggregate(
    [
        {$project: {ab: {$cmp: ['$budget','$clickcost']}}},
        {$match: {ab:{$gt:1}}}
    ]).pretty();

But I was getting wrong result, it returns always 4 document which their budget may or may not be grater than click_cost, which it means it fetch wrong data.

How can I add that comparison to my mongoDB pipeline?

Answer

s7vr picture s7vr · Dec 29, 2016

The problem is not with comparison operator, its the type of value you are comparing. You should change types of variable to Numbers. Change your match to 1, -1 or 0 based on your comparison.

db.bcamp.aggregate(
[
  {$project: {ab: {$cmp: ['$budget','$clickcost']}}},
  {$match: {ab:{$eq:1}}}
]).pretty();

You can use $expr in 3.6 version.

db.bcamp.aggregate(
[
  {$match: {$expr: {$eq: ["$budget", "$clickcost"]}}}
]).pretty();

Or

db.bcamp.find(
 {$expr: {$eq: ["$budget", "$clickcost"]}}
).pretty();