3

I am using aggregation in MongoDB and now I am facing a problem, I want to project my fields based on a condition matching or not.

For example I have a field coupon_type for which I will check if its value is equal to 1 then I will project fields ["curr_ctr", "total_coupons"] otherwise if its value is not equal to 1 then i will project fields ["curr_ctr", "total_coupons", "curr_ctr", "coupons"].

I can use two queries and run them in parallel but I am trying to achieve my result using one single query.

Can anyone please tell me how can I do this in one single query?

UPDATE

My documents are like below

[{ "_id" : ObjectId("5878e1edf1df5a2b69bcf60e"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1eff1df5a2b69bcf60f"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 0 } ,
{ "_id" : ObjectId("5878e1f1f1df5a2b69bcf610"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f3f1df5a2b69bcf611"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f5f1df5a2b69bcf612"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 11 } ,
{ "_id" : ObjectId("5878e1f7f1df5a2b69bcf613"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 110 },
{ "_id" : ObjectId("5878e1f9f1df5a2b69bcf614"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 0 } ]

Now for all coupon_type equal to 0 i want to project fields ["curr_ctr", "total_coupons", "curr_ctr", "coupons"] and for all coupon_type not equal to 0 i want to project fields ["curr_ctr", "total_coupons"]

UPDATE

Actually i want to project coupons array from index n to n+1, where n is the input by the user.

Prakash Kumar
  • 829
  • 1
  • 15
  • 32
  • Yes you can do this using **[$cond](https://docs.mongodb.com/manual/reference/operator/aggregation/cond/)** – Neo-coder Jan 13 '17 at 13:39
  • I know about $cond but how can i use $cond to project diffenrent fields ?? can you show me the code to do this ?? – Prakash Kumar Jan 13 '17 at 13:41
  • 1
    Is better way you can post your sample documents and expected output and what you tried ? – Neo-coder Jan 13 '17 at 13:46
  • As i have already mentioned my fields are all same as above also about what i have tried i saw about this $cond but don't know how can i use this for my scenario. – Prakash Kumar Jan 13 '17 at 14:05

1 Answers1

3

Let consider your collection contain following documents

[{ "_id" : ObjectId("5878e1edf1df5a2b69bcf60e"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1eff1df5a2b69bcf60f"), "coupon_type" : 0 } ,
{ "_id" : ObjectId("5878e1f1f1df5a2b69bcf610"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f3f1df5a2b69bcf611"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f5f1df5a2b69bcf612"), "coupon_type" : 11 } ,
{ "_id" : ObjectId("5878e1f7f1df5a2b69bcf613"), "coupon_type" : 110 },
{ "_id" : ObjectId("5878e1f9f1df5a2b69bcf614"), "coupon_type" : 0 } ]

Now you need to use $eq in project as :

db.collectoin.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["curr_ctr", "total_coupons"],
    "else": ["curr_ctr", "total_coupons", "curr_ctr", "coupons"]
      }
    }
  }
})

As per new Update you should modify query as like this :

db.collection.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["$curr_ctr", "$total_coupons", "$coupons"],
    "else": ["$curr_ctr", "$total_coupons"]
      }
    }
  }
})

UPDATE

As per new update let consider your n given by user for ex. : var n = 1;

now query will be as below :

db.coupon.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["$curr_ctr", "$total_coupons", {
      "coupons": {
        "$slice": ["$coupons", n, n + 1]
      }
    }],
    "else": ["$curr_ctr", "$total_coupons"]
      }
    }
  }
})
Neo-coder
  • 7,715
  • 4
  • 33
  • 52
  • Not sure of two things 1) whether your code will return array of field values, or array of strings. 2) whether OP wants to get array of values. And then checking length of array and getting values by indexes. I bet he wants to get fields of document as fields – Sergey Berezovskiy Jan 13 '17 at 14:54
  • @SergeyBerezovskiy I am also pretty sure that OP need arrays of values, I already asked in comment to shows sample documents and expected output but OP did not explain properly. So I thought OP needs only how to write condition in aggregate that's why I posted it very simple way. Let's see how OP will update question then I will modify answer according to them. – Neo-coder Jan 13 '17 at 17:55
  • sorry but it is not working as i want to project fields that are present in my array. Please see my edited question. thank you anyways. – Prakash Kumar Jan 13 '17 at 18:12
  • @PrakashKumar please check new update answer if you need key names then use `$literal` – Neo-coder Jan 13 '17 at 18:59
  • Can you please see my updated post, actually i want to project array from index n to n+1, can you please tell me how can i possibly do that according to your code. – Prakash Kumar Jan 14 '17 at 18:02
  • Still did not get your point did it's looks like **[$slice](https://docs.mongodb.com/manual/reference/operator/projection/slice/)** – Neo-coder Jan 14 '17 at 19:09
  • yes using $slice but how to project coupons array from index (n to n+1) inside my $cond that is the question ?? – Prakash Kumar Jan 14 '17 at 19:27
  • @PrakashKumar check new update answer I think this will be solve your problem or you will get idea how to implement `$slice` in `project with $cond` – Neo-coder Jan 15 '17 at 12:31
  • @Yogesh can you please help me out here i have another problem n aggregation in mongodb http://stackoverflow.com/questions/41676119/represent-object-present-at-a-position-inside-an-array-in-mongodb-aggregation – Prakash Kumar Jan 16 '17 at 12:11
  • are you there bro ?? – Prakash Kumar Jan 16 '17 at 12:55