Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB聚合管道$匹配顺序_Mongodb_Aggregation Framework_Sharding - Fatal编程技术网

MongoDB聚合管道$匹配顺序

MongoDB聚合管道$匹配顺序,mongodb,aggregation-framework,sharding,Mongodb,Aggregation Framework,Sharding,我有4个碎片的MongoDB集群。我的分片密钥是:{client_id:1,date:1} 使用过的集合有大约50米的文档 我将粘贴1个文档作为示例数据: { "_id" : ObjectId("54e069353e9104db470065e6"), "campaign_name" : "SC - Biker Planet", "adgroup_name" : "motociclista cerca", "client_id" :

我有4个碎片的MongoDB集群。我的分片密钥是:{client_id:1,date:1} 使用过的集合有大约50米的文档

我将粘贴1个文档作为示例数据:

{ "_id" : ObjectId("54e069353e9104db470065e6"), "campaign_name" : "SC - Biker Planet", "adgroup_name" : "motociclista cerca", "client_id" : NumberLong(143), "adgroup_id" : NumberLong(28469), "campaign_id" : NumberLong(849), "device" : "desktop", "clicks" : NumberLong(0), "conv" : NumberLong(0), "cost" : NumberLong(0), "impressions" : NumberLong(1), "date" : ISODate("2014-02-22T05:00:00.000Z") } { “_id”:ObjectId(“54e069353e9104db470065e6”), “运动名称”:“SC-自行车星球”, “adgroup_name”:“Motocicilista cerca”, “客户id”:编号长(143), “adgroup_id”:数字长(28469), “活动id”:编号长(849), “设备”:“桌面”, “点击次数”:数字长(0), “conv”:数字长(0), “成本”:数字长(0), “印象”:数字长(1), “日期”:ISODate(“2014-02-22T05:00:00.000Z”) } 现在,我已经安装了MongoDB 3.0 RC9(带有伟大的wiredTiger存储引擎),我正在比较以下两个查询:

(A)

db.google\u raw\u id.aggregate([{ $match:{ 客户编号:143, 活动名称:“SC-老年人约会”, 日期:{ $gte:ISODate(“2014-01-10T00:00:00.0Z”), $lte:ISODate(“2015-01-10T00:00:00.0Z”) } } }, { $group:{ _id:“$campaign_name”, 成本:{$sum:“$cost”}, 点击:{$sum:$clicks}, 印象:{$sum:$impressions} } }]) 及

(B)

db.google\u raw\u id.aggregate([{ $match:{ 客户编号:143, 日期:{ $gte:ISODate(“2014-01-10T00:00:00.0Z”), $lte:ISODate(“2015-01-10T00:00:00.0Z”) } } }, { $group:{ _id:“$campaign_name”, 成本:{$sum:“$cost”}, 点击:{$sum:$clicks}, 印象:{$sum:$impressions} } }, { $match:{ _id:‘SC-老年人约会’, } }]) 查询A执行大约需要0.35秒,查询B执行大约需要1.1秒,它们都返回相同的结果。 正如您所看到的,它们之间的唯一区别是我将“campaign_name”过滤器从$group之前的$match移动到$group之后的$match

由于只有在第一个$match中没有其他筛选器,或者我的配置中有错误,所以碎片密钥{client_id,date}才能快速工作,所以使用这种方法可以吗

更新

这里我解释了使用MongoDB聚合的查询A和查询B

这里我简化了查询A和查询B以供使用

我还对campaign_name进行了索引,但如果在第一次匹配中使用campaign_name,聚合查询似乎会变慢,因为这不是shard key的一部分,这就是Mongo必须签入多个shard的原因

对我来说,这就是为什么查询B更快的逻辑解释。 在查询B中,Mongo将结果简化为更小的数据集,而不是将campaign_名称应用于该数据集,因此速度更快,并且不会覆盖其他碎片。
我只是希望MongoDB能够自动计算:)

A更快,因为在第一次“匹配”之后,您已经对记录进行了分组(“匹配”之后的所有结果都具有相同的“活动名称”)。在“组”中,只需计算它们


B速度较慢,因为在第一场比赛后,您有更多的结果,并且“组”中需要处理更多的数据。换句话说,脚本将计算所有找到的活动的结果。

这太令人惊讶了。只要看一看,B的计算量就大得多(因为我不太了解集合中的实际文档,只知道它们的形状)。这两条管道应该总是产生相同的结果,因此如果后者更好,那么现在就使用它。如果您想检查为什么B更快,请为这两个查询发布解释。您需要将两个初始的
$match
阶段转换为查找查询并运行解释。我已经用两个解释查询链接更新了我的帖子。我认为B应该只查询1个碎片,因为碎片键是{client_id,date},但是当使用campaign_name时,它也会查询其他碎片。至少对我来说这听起来合乎逻辑。所以我认为最好的方法是在第一个$match中只使用切分键字段,然后再应用另一个$match。这是很多信息,但我看不到任何东西来解释时间上的差异。包括
campaign\u name
不会让它查询到更多的碎片-它仍然可以使用
client\u id
date
以查询为目标。这是很多信息,但我看不到任何东西来解释时间上的差异。包含
campaign\u name
不会使其查询比已经查询的碎片更多的碎片-它仍然可以使用
client\u id
和`date>以查询为目标。 db.google_raw_id.aggregate([{ $match: { client_id: 143, campaign_name: 'SC - Dating For Seniors', date: { $gte: ISODate("2014-01-10T00:00:00.0Z"), $lte: ISODate("2015-01-10T00:00:00.0Z") } } }, { $group: { _id: "$campaign_name", cost: {$sum: "$cost"}, clicks: {$sum: "$clicks"}, impressions: {$sum: "$impressions"} } }]) db.google_raw_id.aggregate([{ $match: { client_id: 143, date: { $gte: ISODate("2014-01-10T00:00:00.0Z"), $lte: ISODate("2015-01-10T00:00:00.0Z") } } }, { $group: { _id: "$campaign_name", cost: {$sum: "$cost"}, clicks: {$sum: "$clicks"}, impressions: {$sum: "$impressions"} } }, { $match: { _id: 'SC - Dating For Seniors', } }])