【问题标题】:In mongodb know index of array element matched with $in operator?在 mongodb 中知道与 $in 运算符匹配的数组元素的索引吗?
【发布时间】:2017-04-26 16:40:36
【问题描述】:

我正在将聚合与 mongoDB 一起使用,现在我在这里遇到了一个问题,我正在尝试使用 $in 运算符匹配我的输入数组中存在的文档。现在我想知道输入数组中元素的索引,谁能告诉我该怎么做。

我的代码

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 {

            }
        });

优惠券模型架构

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

更新- 正如user3124885所建议的那样,聚合在性能上并不好,任何人都可以告诉我聚合和mongodb中普通查询之间的性能差异。哪个更好??

更新- 我在 SOmongodb-aggregation-match-vs-find-speed 上阅读了这个问题。在这里,用户自己评论说两者都需要相同的时间,而且通过看到vlad-z 的答案,我认为聚合更好。如果你们中的任何人都曾在 mongodb 上工作过,请告诉我您对此有何看法。

更新- 我使用了包含 30,000 行的示例 json 数据,并尝试与聚合匹配 v/s 查找查询聚合在 180 毫秒内执行,而查找查询需要 220 毫秒。我还运行了 $lookup,它也花费了不超过 500 毫秒的时间,所以认为聚合比普通查询快一点。如果你们中有人尝试过使用聚合,请纠正我,如果没有,那为什么??

更新-

我阅读了这篇文章,其中用户使用以下代码代替 $zip SERVER-20163,但我不知道如何使用以下代码解决我的问题。那么谁能告诉我如何使用下面的代码来解决我的问题。

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

现在任何人都可以帮助我,这对我来说真的是一个很大的帮助。

【问题讨论】:

  • 为什么不直接执行find({_id: {$in: coupons_ids}}),然后在coupons_ids 中搜索返回的文档中的_id 值?
  • 因为使用聚合服务器过载会减少,这就是为什么要考虑使用聚合?另外你能告诉我聚合比普通查询慢还是慢很多?此外,我还运行了一些案例,其中我有 30000 个样本数据并且聚合比正常查询快一点。如果我的方向错误,请纠正我??
  • 匹配元素后你想在聚合查询中做什么?
  • @KevinSmith 我想以与匹配的 coupon_id 相同的索引返回 coupon_ctr
  • 有没有couponmodelcollection里面的文档结构的例子

标签: mongodb mongoose aggregation-framework


【解决方案1】:

假设我们在数据库集合中有以下内容:

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

我们希望在集合中搜索以下 id

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

然后我们必须建立一个动态投影状态,以便我们可以投影正确的索引,所以我们必须将每个 id 映射到其对应的索引

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

然后我们可以将其注入到我们的聚合管道中

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

运行上面的代码现在将输出每个 _id 及其在 coupons_ids 数组中的对应索引

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

但是我们也可以在最后添加更多的项目到管道中并引用$index来获取当前匹配的索引。

【讨论】:

  • 抱歉,您误解了我的问题,我希望 coupon_ctr 值与 _id 一起返回。
  • 你的问题与coupon_ctr没有任何关系,你能详细解释一下吗?
  • 我很抱歉,但让我解释一下,实际上你是从数据库中打印索引,但我想要根据我传递的内部数组 coupon_ids 的索引,所以输出应该是这个 { "_id" : " a", "index" : 1 } { "_id" : "c", "index" : 0 }
  • 这是数组的索引...我们刚刚注入了一些投影,因此我们可以计算出数组中的正确位置...如果您查看我的输出,它是相同的正如你所描述的
  • 它为每个匹配创建条件以返回索引,以便可以将其放置在投影中:-)
【解决方案2】:

我认为您可以以更快的方式完成此操作,只需检索数组并手动搜索即可。请记住,聚合不会给您带来性能。

【讨论】:

  • 是的,但是服务器上的计算使服务器繁忙,这也是一个主要问题,这就是尝试使用聚合的原因。如果您认为我的想法有误,请赐教。
  • 聚合也比普通查询慢得多,因为我在 SO 问题上看到了它,然后它们都需要相同的时间来运行查询,如果错了,请与我联系??也感谢您在这里发布答案。
  • 没有聚合是MongoDB中最低的操作,而不是其他操作。在您的情况下,如果您在聚合中没有其他操作要做,我只是向您宣传:
  • 聚合也不是最低的,因为 map reduce 比聚合慢很多倍。
  • 我看到了你更新的帖子。 MongoDB是一个NOSQL数据库,所以你必须以非关系的方式创建数据库结构。
【解决方案3】:

//$match,$in,$and

    $match:{
        $and:[        
        {"uniqueID":{$in:["CONV0001"]}},
        {"parentID":{$in:["null"]}},
        ]
       }
   }])

【讨论】:

  • @devpato 答案中没有链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 2012-03-22
  • 2015-01-03
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多