【问题标题】:Mongodb unwind and match VS match and unwindMongodb unwind and match VS match and unwind
【发布时间】:2017-08-09 21:16:59
【问题描述】:

我希望通过最小化要展开的记录数来优化 MongoDB 性能。

我喜欢:

unwind(injectionRecords),
match("machineID" : "machine1"),
count(counter)

但是由于数据量很大,展开操作需要很多时间,然后从展开匹配。 它展开所有 4 条记录,然后匹配结果中的 machineID 并给我计数。

相反,我想做类似的事情:

match("machineID": "machine1"),
unwind(injectionRecords)
count(counter)

因此,它会匹配具有 machineID 的记录并展开仅 2 而不是 4 并给我它的计数。

这可能吗?我该怎么做?

这里是示例文档,

{   
   "_id" : ObjectId("5981c24b90a7c215e4f166dd"),
    "machineID" : "machine1",
    "injectionRecords" : [ 
        {
            "startTime" : ISODate("2017-08-02T17:45:04.779+05:30"),
            "endTime" : ISODate("2017-08-02T17:45:07.763+05:30"),
            "counter" : 1
        }, 
        {
            "startTime" : ISODate("2017-08-02T17:45:24.417+05:30"),
            "endTime" : ISODate("2017-08-02T17:45:27.402+05:30"),
            "counter" : 2
        }
    ]
},
{   
   "_id" : ObjectId("5981c24b90a7c215e4f166de"),
    "machineID" : "machine2",
    "injectionRecords" : [ 
        {
            "startTime" : ISODate("2017-08-02T17:46:04.779+05:30"),
            "endTime" : ISODate("2017-08-02T17:46:07.763+05:30"),
            "counter" : 1
        }, 
        {
            "startTime" : ISODate("2017-08-02T17:46:24.417+05:30"),
            "endTime" : ISODate("2017-08-02T17:46:27.402+05:30"),
            "counter" : 2
        }
    ]
}

【问题讨论】:

  • 当然可以使用 (1) 匹配然后 (2) 展开来订购聚合管道,因此您问题的答案可能取决于 您的特定匹配 是否实际适用在数据展开之前。您能否更新您的问题以包含示例文档以及您当前的放松和匹配阶段?
  • @glitch 你能针对我的问题发布优化查询吗?
  • @RicardoRocha 请不要对“mongodb”之类的词使用代码格式。 For more information look at this
  • @jmattheis 谢谢你的提示 :)
  • OP 可能运行的是一个非常旧的版本(3.0 或更早版本),因为 MongoDB 在 3.2(2015 年 11 月发布)安全时会自动重新排序这两个阶段。

标签: mongodb mongodb-query


【解决方案1】:

以下查询将返回给定machineId 的计数injectionRecords。我认为这就是你想要的。

db.collection.aggregate([
    {$match: {machineID: 'machine1'}},
    {$unwind: '$injectionRecords'},
    {$group:{_id: "$_id",count:{$sum:1}}}
])

当然,这个查询(在匹配之前展开)在功能上是等效的:

db.collection.aggregate([
    {$unwind: '$injectionRecords'},
    {$match: {machineID: 'machine1'}},
    {$group:{_id: "$_id",count:{$sum:1}}}
])

但是,使用说明运行该查询...

db.collection.aggregate([
    {$unwind: '$injectionRecords'},
    {$match: {machineID: 'machine1'}},
    {$group:{_id: "$_id",count:{$sum:1}}}
], {explain: true})

... 表明展开阶段适用于整个集合,而如果您在展开之前匹配,则仅展开匹配的文档。

【讨论】:

  • 非常感谢@glitch。我不太确定查询执行的阶段,但“{explain: true}”很有帮助。
  • 不确定您检查的是哪个版本,但几年来的解释表明,在安全的情况下,$match 将在 $unwind 前面自动交换。 > db.collection.aggregate([ {$unwind: '$injectionRecords'}, {$match: {machineID: 'machine1'}}, {$group:{_id: "$_id",count:{$sum:1 }}} ], {explain: true}) { "stages" : [ { "$cursor" : { "query" : { "machineID" : "machine1" }, ... } }, { "$unwind" : { "路径" : "$injectionRecords" } }, {$group: 等等...
猜你喜欢
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 2017-08-27
  • 2021-05-04
  • 2013-12-26
  • 2021-11-12
相关资源
最近更新 更多