1

In aggregation project array element from index x to y where x is defined inside collection and y is an array element corresponding to the index of the array element which is matched. Please see below example then it will become quite easier to understand what i am trying to say.

coupons collection

{"coupon_id": "coupon01", "codes": ["FLAT30", "FLAT50", "FLAT70", "FLAT90"], "curr_index": 0}

For example see below example code here i am trying to get coupon codes starting from curr_index to (curr_index + n) where n is the number in coupon_ctrs corresponding to the index of coupons_ids example- for id "584559bd1f65d363bd5d25fd" n is 1, for id "58455a5c1f65d363bd5d2600" n is 2 and for the id "584878eb0005202c64b0cc5d" n is 3.

coupons_ctrs = [1, 2, 3];
coupons_ids = ["584559bd1f65d363bd5d25fd", "58455a5c1f65d363bd5d2600", "584878eb0005202c64b0cc5d"];

int n = 2;
couponmodel.aggregate(
        { $match : { '_id': { $in : coupons_ids }} },
        { $project: {_id:0, codes : /* How to use slice here so that codes array will be returned between cur_index and (curr_index + coupons_ctr corresponding to the index coupon id is found, example- for _id "584559bd1f65d363bd5d25fd" it should be 1 and so on) */} },
        function(err, docs) {
            if (err) {

            } else {

            }
        });

UPDATE

As suggested by Styvane i could use $zip and it would work perfect but as i am using mongoDB 3.2.11 so i can't use it, so what can be the solution for using functionality of $zip in mongodb 3.2.11 ??

Can anyone please tell me how can i include this coupon_ctrs array and use it inside aggregation pipeline.

1 Answer 1

1

You need to apply a $slice expression to each element in the "coupons_ctrs" array using the $map operator which means that we use the literal "coupons_ctrs" array as "input" to $map.

let coupons_ids = [
    "584559bd1f65d363bd5d25fd", 
    "58455a5c1f65d363bd5d2600", 
    "584878eb0005202c64b0cc5d"
];

let coupons_ctrs = [1, 2, 3];

db.couponmodel.aggregate(
    [
        { "$match" : { "_id": { "$in" : coupons_ids } } },
        { "$project": { 
            "codes":  { 
                "$map": { 
                    "input": coupons_ctrs, 
                    "as": "n", 
                    "in": { 
                        "$slice": [ 
                            "$codes", 
                            "$curr_index", 
                            { "$add": [ "$curr_index", "$$n" ] } 
                        ]
                    }
                }
            }
        }}
    ]
)

Which yields:

{
    "codes" : [
        [ "FLAT30" ],
        [ "FLAT30", "FLAT50" ],
        [ "FLAT30", "FLAT50",  "FLAT70" ]
    ]
}

In MongoDB 3.4 we can use the $zip operator to do this:

db.couponmodel.aggregate(     
    [ 
        { "$project": {
            "codes":  {
                "$map": {
                    "input": { 
                        "$zip": { 
                            "inputs": [ coupons_ids, coupons_ctrs ] 
                        } 
                    }, 
                    "as": "item",
                    "in": {  
                        "coupon_id": { "$arrayElemAt": [ "$$item", 0 ] },
                        "value": {          
                            "$slice": [  
                                "$codes",       
                                "$curr_index",    
                                { "$add": [ 
                                    "$curr_index", 
                                    { "$arrayElemAt": [ "$$item", 1 ] } 
                                ] }                          
                            ]
                         }
                    }     
                } 
            } 
        }}     
    ] 
)

which return something like this:

{
    "codes" : [
        {
             "coupon_id" : "584559bd1f65d363bd5d25fd",
             "value" : [ "FLAT30" ]
        },
        {
             "coupon_id" : "58455a5c1f65d363bd5d2600",
             "value" : [ "FLAT30", "FLAT50" ],
        },
        {
             "coupon_id" : "584878eb0005202c64b0cc5d",
             "value" : [ "FLAT30", "FLAT50",  "FLAT70" ]
        }
    ]
}
Sign up to request clarification or add additional context in comments.

10 Comments

In your code where it is defined that for id: "584559bd1f65d363bd5d25fd" n will be 1, i mean is there any surety that for each id that is matching "n" will be the same index element in "coupon_ctr". ??
@PrakashKumar yes it will but you need to provide the "coupons_ids" elements index need to be in the same order as the "coupons_ctrs" elements as you've shown.
yes it is in smae order but how can this code intenrally do that can you please explain ??
@PrakashKumar did you run the code? Is it working the way you expect?
sorry but not for first id i am getting three codes [["GETFREE"],["GETFREE"],["GETFREE"]], for second id i am getting [["FET50"],["FET50"],["FET50"]] and for third i am getting [["versace"],["versace","versace"],["versace","versace"]].
|

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.