如何在MongoDB中的$ match中使用聚合运算符(例如$ year或$ dayOfMonth)? [英] How do I use aggregation operators in a $match in MongoDB (for example $year or $dayOfMonth)?

查看:387
本文介绍了如何在MongoDB中的$ match中使用聚合运算符(例如$ year或$ dayOfMonth)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个充满了具有created_date属性的文档的集合。我想通过汇总管道发送这些文档,以对它们进行一些处理。理想情况下,我想先使用$ match过滤它们,然后再对它们进行任何其他处理,以便我可以利用索引,但是我不知道如何在我的新方法中使用新的$ year / $ month / $ dayOfMonth运算符$ match表达式。

I have a collection full of documents with a created_date attribute. I'd like to send these documents through an aggregation pipeline to do some work on them. Ideally I would like to filter them using a $match before I do any other work on them so that I can take advantage of indexes however I can't figure out how to use the new $year/$month/$dayOfMonth operators in my $match expression.

关于如何在$ project操作中使用运算符的例子不胜枚举,但我担心将$ project作为第一步管道,然后我就无法访问索引(MongoDB文档指示第一个表达式必须是$ match才能利用索引)。

There are a few examples floating around of how to use the operators in a $project operation but I'm concerned that by placing a $project as the first step in my pipeline then I've lost access to my indexes (MongoDB documentation indicates that the first expression must be a $match to take advantage of indexes).

样本数据:

{
    post_body: 'This is the body of test post 1',
    created_date: ISODate('2012-09-29T05:23:41Z')
    comments: 48
}
{
    post_body: 'This is the body of test post 2',
    created_date: ISODate('2012-09-24T12:34:13Z')
    comments: 10
}
{
    post_body: 'This is the body of test post 3',
    created_date: ISODate('2012-08-16T12:34:13Z')
    comments: 10
}

我想通过汇总管道运行此操作,以获取对9月份所有帖子的总评论

I'd like to run this through an aggregation pipeline to get the total comments on all posts made in September

{
    aggregate: 'posts',
    pipeline: [
         {$match:
             /*Can I use the $year/$month operators here to match Sept 2012?
             $year:created_date : 2012,
             $month:created_date : 9
             */
             /*or does this have to be 
             created_date : 
                  {$gte:{$date:'2012-09-01T04:00:00Z'}, 
                  $lt: {$date:'2012-10-01T04:00:00Z'} }
             */
         },
         {$group:
             {_id: '0',
              totalComments:{$sum:'$comments'}
             }
          }
    ]
 }

此方法有效,但是匹配项无法访问任何索引更复杂的查询:

This works but the match loses access to any indexes for more complicated queries:

{
    aggregate: 'posts',
    pipeline: [
         {$project:
              {
                   month : {$month:'$created_date'},
                   year : {$year:'$created_date'}
              }
         },
         {$match:
              {
                   month:9,
                   year: 2012
               }
         },
         {$group:
             {_id: '0',
              totalComments:{$sum:'$comments'}
             }
          }
    ]
 }


推荐答案

您已经发现,不能对不在文档中的字段进行$ match(它与find的工作方式完全相同),如果您首先使用$ project,那么您将失去使用的能力索引。

As you already found, you cannot $match on fields that are not in the document (it works exactly the same way that find works) and if you use $project first then you will lose the ability to use indexes.

您可以做的是合并您的努力,如下所示:

What you can do instead is combine your efforts as follows:

{
    aggregate: 'posts',
    pipeline: [
         {$match: {
             created_date : 
                  {$gte:{$date:'2012-09-01T04:00:00Z'}, 
                  $lt:  {date:'2012-10-01T04:00:00Z'} 
                  }}
             }
         },
         {$group:
             {_id: '0',
              totalComments:{$sum:'$comments'}
             }
          }
    ]
 }

以上仅提供汇总对于9月份,如果您想汇总多个月,则可以例如:

The above only gives you aggregation for September, if you wanted to aggregate for multiple months, you can for example:

{
    aggregate: 'posts',
    pipeline: [
         {$match: {
             created_date : 
                  { $gte:'2012-07-01T04:00:00Z', 
                    $lt: '2012-10-01T04:00:00Z'
                  }
         },
         {$project: {
              comments: 1,
              new_created: {
                        "yr" : {"$year" : "$created_date"},
                        "mo" : {"$month" : "$created_date"}
                     }
              }
         },
         {$group:
             {_id: "$new_created",
              totalComments:{$sum:'$comments'}
             }
          }
    ]
 }

,您会得到一些回报像这样:

and you'll get back something like:

{
    "result" : [
        {
            "_id" : {
                "yr" : 2012,
                "mo" : 7
            },
            "totalComments" : 5
        },
        {
            "_id" : {
                "yr" : 2012,
                "mo" : 8
            },
            "totalComments" : 19
        },
        {
            "_id" : {
                "yr" : 2012,
                "mo" : 9
            },
            "totalComments" : 21
        }
    ],
    "ok" : 1
}

这篇关于如何在MongoDB中的$ match中使用聚合运算符(例如$ year或$ dayOfMonth)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆