Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.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 如何查询嵌入文档上的$regex以计算不同的值_Mongodb_Aggregation Framework - Fatal编程技术网

Mongodb 如何查询嵌入文档上的$regex以计算不同的值

Mongodb 如何查询嵌入文档上的$regex以计算不同的值,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我收集了以下格式的文件: { "_id" : ObjectId("abc"), "mobile" : "123456789", "channels" : [ { "name" : "email.xz", "type" : "a", "properties" : [ { "provider" : "outl

我收集了以下格式的文件:

{ 
    "_id" : ObjectId("abc"), 
    "mobile" : "123456789", 
    "channels" : [
        {
            "name" : "email.xz", 
            "type" : "a", 
            "properties" : [
                {
                    "provider" : "outlook"
                }
            ]
        }, 
        {
            "name" : "sms", 
            "type" : "sms"
            }
    ], 

}
我需要找到至少有一个频道名称以“.xz”结尾的客户,但前提是提供商存在并且有一个值,然后返回每个频道的客户数。例如:

email.xz = 10
sms.xz = 5
push.xz = 7
我试着使用下面的聚合函数,但它得到了符合条件的所有客户的计数

db.consumers.aggregate(
{$match: {"channels.name": {$regex: ".xz$"}, 
"notificationChannels.properties.provider": { $exists: true }}},
{$group: {_id: "channels.name"},
count: {$sum: 1}})
数组,然后再次以相同的方式。第一个匹配项仅用于选择文档,您要筛选:

db.consumers.aggregate(
  { $match: {
    "channels.name": {$regex: ".xz$"}, 
    "channels.properties.provider": { $exists: true }
  }},
  { $unwind: "$channels" },
  { $match: {
    "channels.name": {$regex: ".xz$"}, 
    "channels.properties.provider": { $exists: true }
  }},
  { $group:{
    "_id": "$channels.name",
    "count": {$sum: 1}
  }}
)

因为您想从数组的“内部”打开一个键,所以无论如何都需要打开它。由于您只需要与您的条件匹配的数组项,因此使用a的唯一方法是在

$match之后通过a,这在本例中是多余的query@kailashyogeshwar不,当然不是。最重要的是,在任何聚合管道中始终使用初始阶段,以解决索引问题并理想地减少结果。您似乎认为“每个文档”都将满足条件,并且您只需要在
$unwind
之后使用后续的
$match
来过滤数组内容。不幸的是,你可能从之前看到的非常糟糕的例子中得到了这个观点,而不考虑这一点。这里的两个
$match
阶段都在做两件不同的事情。因此,这不是一个错误,而是一个有意的好设计。也许在$group中使用“\u id:”$channels.name“”,会提供更多信息?@GerardH.Pille谢谢。过度热情的复制和粘贴,并没有注意到这一点。谢谢。从未与MongoDB合作过,经过一整天的尝试,这一练习毫无进展。事实上,我没有意识到我在使用3.2(在Debian上),但看着3.6手册,并没有提高我的机会。您的答案应该出现在教程中。