MongoDB-使用聚合而不是日期范围的常规范围查询是否明智?

MongoDB-使用聚合而不是日期范围的常规范围查询是否明智?,mongodb,mongoose,aggregation-framework,Mongodb,Mongoose,Aggregation Framework,我试图在MongoDB中执行日期范围查询。假设我想找到“2018年5月”创建的记录。现在根据知识,我们可以通过以下方式实现这一点 一种是对createdAt进行简单的范围查询。前任。 {createdAt:{$gte:ISODate('2018-05-01'),$lte:ISODate('2018-05-31')} 另一种方法是聚合 聚合([{$project:{$year:{$year:'$createdAt'},month:{$month:'$createdAt'}), {$match

我试图在MongoDB中执行日期范围查询。假设我想找到“2018年5月”创建的记录。现在根据知识,我们可以通过以下方式实现这一点

  • 一种是对createdAt进行简单的范围查询。前任。
    
    {createdAt:{$gte:ISODate('2018-05-01'),$lte:ISODate('2018-05-31')}
    

  • 另一种方法是聚合
    
    聚合([{$project:{$year:{$year:'$createdAt'},month:{$month:'$createdAt'}),
    {$match:{年份:2018,月份:5}}])
    

  • 那么,如果我们可以通过简单的查询获得结果,那么什么时候使用聚合呢?如果上述查询或方法不正确或陈旧,请给出更正。我正在Compass中对此进行测试


    谢谢

    您不需要
    $project
    阶段(事实上,您编写投影的方式您的输出文档将只包含投影值和
    \u id
    字段,这可能是您想要的,也可能不是您想要的)。因此,剩下的是您的聚合查询只是一个
    $match
    。可以假设查询执行时间相同,只是对阶段处理有轻微的惩罚。此外,我个人认为“正常的”
    find()
    如果聚合框架还没有完全实现的话,那么它几乎可以在内部聚合到聚合框架中。保留两种查询数据的方法是没有意义的


    为了清楚起见,我个人倾向于
    find()
    版本。

    您不需要
    $project
    阶段(事实上,您编写投影的方式您的输出文档将只包含投影值和
    \u id
    字段,这可能是您想要的,也可能不是您想要的)。因此,剩下的是您的聚合查询只是一个
    $match
    。可以假设查询执行时间相同,只是对阶段处理有轻微的惩罚。此外,我个人认为“正常的”
    find()
    如果聚合框架还没有完全实现的话,那么它几乎可以在内部聚合到聚合框架中。保留两种查询数据的方法是没有意义的


    为了清楚起见,我个人倾向于使用
    find()
    版本。

    如果您可以通过简单的查询来实现,请保持简单。 有许多框架可以轻松支持查询,但不支持聚合

    聚合更难编写和维护。在某些情况下,您确实需要它们(比如在处理数组或子文档时),但如果不需要,请使用find()保存它。 有关何时需要聚合的示例:

    另外,我不确定聚合代码是否与find()代码相同。 如果检查正确,则首先使用$project stage,然后进行匹配。 这意味着您正在投影数据库的所有对象,然后在它们之间进行匹配,因为您没有使用$match启动聚合。 如果有许多对象,这可能会非常慢

    另外,$match仅在第一阶段使用索引:

    尽可能早地将$match放入聚合管道中。 因为$match限制了聚合中的文档总数 管道,早期的$match操作将处理量降至最低 如果你把一个$match放在 在管道中,查询可以像其他查询一样利用索引 db.collection.find()或db.collection.findOne()


    如果你能用一个简单的查询来完成,就保持它的简单。 有许多框架可以轻松支持查询,但不支持聚合

    聚合更难编写和维护。在某些情况下,您确实需要它们(比如在处理数组或子文档时),但如果不需要,请使用find()保存它。 有关何时需要聚合的示例:

    另外,我不确定聚合代码是否与find()代码相同。 如果检查正确,则首先使用$project stage,然后进行匹配。 这意味着您正在投影数据库的所有对象,然后在它们之间进行匹配,因为您没有使用$match启动聚合。 如果有许多对象,这可能会非常慢

    另外,$match仅在第一阶段使用索引:

    尽可能早地将$match放入聚合管道中。 因为$match限制了聚合中的文档总数 管道,早期的$match操作将处理量降至最低 如果你把一个$match放在 在管道中,查询可以像其他查询一样利用索引 db.collection.find()或db.collection.findOne()


    这是我的经验,通常在你做了一个基本的<代码>()(代码)>之后,你的需求就改变了,需要流水线的力量。例如,考虑下面的文档:

    { "_id" : 0, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 1, "date" : ISODate("2018-01-07T00:00:00Z") }
    { "_id" : 2, "date" : ISODate("2018-01-03T00:00:00Z") }
    { "_id" : 3 }
    { "_id" : 4, "date" : ISODate("2018-01-20T00:00:00Z") }
    { "_id" : 5 }
    { "_id" : 6 }
    { "_id" : 7, "date" : ISODate("2018-01-18T00:00:00Z") }
    { "_id"  :8, "date" : ISODate("2018-01-10T00:00:00Z") }
    

    我们希望找到所有日期:P>这是我的经验,通常在你做了基本的<代码>()(代码)>之后,你的需求就改变了,需要流水线的力量。例如,考虑下面的文档:

    { "_id" : 0, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 1, "date" : ISODate("2018-01-07T00:00:00Z") }
    { "_id" : 2, "date" : ISODate("2018-01-03T00:00:00Z") }
    { "_id" : 3 }
    { "_id" : 4, "date" : ISODate("2018-01-20T00:00:00Z") }
    { "_id" : 5 }
    { "_id" : 6 }
    { "_id" : 7, "date" : ISODate("2018-01-18T00:00:00Z") }
    { "_id"  :8, "date" : ISODate("2018-01-10T00:00:00Z") }
    

    我们希望找到所有where date,那么在简单的find查询中应用多个年份和月份过滤器可以吗?对于这种复杂的查询,我们必须使用聚合?在find()中使用多个过滤器非常合适@parth:还有
    $和
    。我的经验是,它并不总是喜欢以这种方式在同一个字段上进行多个查询,所以我有时会使用
    $和
    来进行查询。那么,在简单的查找查询中应用多年和月筛选,或者对于这种复杂的查询,我们必须使用聚合,这是非常好的,不是o在find()中使用多个过滤器。@parth:还有
    $和
    。我的经验是,它并不总是喜欢以这种方式在同一字段上进行多个查询,因此有时我会使用
    $和
    进行查询
    db.foo.aggregate([
    {$match: {"$or": [ {"date": {$lte: new ISODate("2018-01-15")}}, {"date": {$exists: false}} ] }}
    ]);
    
    { "_id" : 0, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 1, "date" : ISODate("2018-01-07T00:00:00Z") }
    { "_id" : 2, "date" : ISODate("2018-01-03T00:00:00Z") }
    { "_id" : 3 }
    { "_id" : 5 }
    { "_id" : 6 }
    { "_id" : 8, "date" : ISODate("2018-01-10T00:00:00Z") }
    
    db.foo.aggregate([
    {$match: {"$or": [ {"date": {$lte: new ISODate("2018-01-15")}}, {"date": {$exists: false}} ] }}
    ,{$sort: {"date":1}}
    ]);
    
    { "_id" : 3 }
    { "_id" : 5 }
    { "_id" : 6 }
    { "_id" : 2, "date" : ISODate("2018-01-03T00:00:00Z") }
    { "_id" : 1, "date" : ISODate("2018-01-07T00:00:00Z") }
    { "_id" : 0, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 8, "date" : ISODate("2018-01-10T00:00:00Z") }
    
    db.foo.aggregate([
    {$match: {"$or": [ {"date": {$lte: new ISODate("2018-01-15")}}, {"date": {$exists: false}} ] }}
    ,{$addFields: {"date": {$ifNull: [ "$date", new ISODate("3000-01-01")] }}}
    ,{$sort: {"date":1}}
    ]);
    
    { "_id" : 2, "date" : ISODate("2018-01-03T00:00:00Z") }
    { "_id" : 1, "date" : ISODate("2018-01-07T00:00:00Z") }
    { "_id" : 0, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 8, "date" : ISODate("2018-01-10T00:00:00Z") }
    { "_id" : 3, "date" : ISODate("3000-01-01T00:00:00Z") }
    { "_id" : 5, "date" : ISODate("3000-01-01T00:00:00Z") }
    { "_id" : 6, "date" : ISODate("3000-01-01T00:00:00Z") }