1

I have a collection with documents which look like this:

{
    "campaignType" : 1,
    "allowAccessControl" : true,
    "userId" : "108028399"
}

I'd like to query this collection using aggregation framework and have a result which looks like this:

{
    "campaignType" : ["APPLICATION"],
    "allowAccessControl" : "true",
    "userId" : "108028399",
}

You will notice that:

  • campaignType field becomes and array
  • the numeric value was mapped to a string

Can that be done using aggregation framework?

I tried looking at $addToSet and $push but had no luck.

Please help.

Thanks

1 Answer 1

1

In either case here it is th $cond operator from the aggregation framework that is your friend. It is a "ternary" operator, which means it evaluates a condition for true|false and then returns the result based on that evaluation.

So for modern versions from MongoDB 2.6 and upwards you can $project with usage of the $map operator to construct the array:

db.campaign.aggregate([
    { "$project": {
        "campaignType": {
            "$map": {
                "input": { "$literal": [1] },
                "as": "el",
                "in": {
                    "$cond": [
                        { "$eq": [ "$campaignType", 1 ] },
                        "APPLICATION",
                        false
                    ]
                }
            }
        },
        "allowAcessControl" : 1,
        "userId": 1
    }}
])

Or generally in most versions you can simply use the $push operator in a $group pipeline stage:

db.campaign.aggregate([
    { "$group": {
        "_id": "$_id",
        "campaignType": {
            "$push": {
                "$cond": [
                     { "$eq": [ "$campaignType", 1 ] },
                     "APPLICATION",
                     false
                 ]
            }
        },
        "allowAccessControl": { "$first": "$allowAccessControl" },
        "userId": { "first": "$userId" }
    }}
])

But the general concept if that you use "nested" expressions with the $cond operator in order to "test" and return some value that matches your "mapping" condition and do that with another operator that allows you to produce an array.

Sign up to request clarification or add additional context in comments.

2 Comments

Amazing, thank you! I'm using Talend and thus forced to use mongo 2.5.. I'm wondering what is the meaning of '{ "$first": "$allowAccessControl" }'? Again - thanks a lot!
@Leo The $first operator is a "grouping operator" in the aggregation API. It returns the "first" match within the "grouping key" specified in _id for that pipeline stage. BTW MongoDB 2.5 as with most verisoning systems means a "development" revision since the minor version is an odd number. Any production code that depends on a "development" release is unreliable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.