In mongodb know index of array element matched wit

2019-01-20 06:20发布

问题:

I am using aggregation with mongoDB now i am facing a problem here, i am trying to match my documents which are present in my input array by using $in operator. Now i want to know the index of the lement from the input array now can anyone please tell me how can i do that.

My code

var coupon_ids = ["58455a5c1f65d363bd5d2600", "58455a5c1f65d363bd5d2601","58455a5c1f65d363bd5d2602"]
couponmodel.aggregate(
        { $match : { '_id': { $in : coupons_ids }} },
        /* Here i want to know index of coupon_ids element that is matched because i want to perform some operation in below code */
        function(err, docs) {
            if (err) {

            } else {

            }
        });

Couponmodel Schema

var CouponSchema = new Schema({
    category: {type: String},
    coupon_name: {type: String}, // this is a string
});

UPDATE- As suggested by user3124885 that aggregation is not better in performance, can anyone please tell me the performance difference between aggregation and normal query in mongodb. And which one is better ??

Update- I read this question on SO mongodb-aggregation-match-vs-find-speed. Here the user himself commented that both take same time, also by seeing vlad-z answer i think aggregation is better. Please if anyone of you have worked on mongodb Then please tell me what are your opinion about this.

UPDATE- I used sample json data containing 30,000 rows and tried match with aggregation v/s find query aggregation got executed in 180 ms where find query took 220ms. ALso i ran $lookup it is also taking not much than 500ms so think aggregation is bit faster than normal query. Please correct me guys if any one of you have tried using aggregation and if not then why ??

UPDATE-

I read this post where user uses below code as a replacement of $zip SERVER-20163 but i am not getting how can i solve my problem using below code. So can anybody please tell me how can i use below code to solve my issue.

{$map: {
    input: {
        elt1: "$array1",
        elt2: "$array2"
    },
    in: ["$elt1", "$elt2"]
}

Now can anyone please help me, it would be really be a great favor for me.

回答1:

So say we have the following in the database collection:

> db.couponmodel.find()
{ "_id" : "a" }
{ "_id" : "b" }
{ "_id" : "c" }
{ "_id" : "d" }

and we wish to search for the following ids in the collections

var coupons_ids = ["c", "a" ,"z"];

We'll then have to build up a dynamic projection state so that we can project the correct indexes, so we'll have to map each id to its corresponding index

var conditions = coupons_ids.map(function(value, index){
    return { $cond: { if: { $eq: ['$_id', value] }, then: index, else: -1 } };
});

Then we can then inject this in to our aggregation pipeline

db.couponmodel.aggregate([
    { $match : { '_id' : { $in : coupons_ids } } },
    { $project: { indexes : conditions } },
    { $project: {
        index : {
            $filter: { 
                input: "$indexes", as: "indexes", cond: { $ne: [ "$$indexes", -1 ] }
                }
            }
        } 
    },
    { $unwind: '$index' }
]);

Running the above will now output each _id and it's corresponding index within the coupons_ids array

{ "_id" : "a", "index" : 1 }
{ "_id" : "c", "index" : 0 }

However we can also add more items in to the pipeline at the end and reference $index to get the current matched index.



回答2:

I think you could do it in a faster way simply retrieving the array and search manually. Remember that aggregation don't give you performance.