4

我想加快对我的 mongoDB 的查询,该查询使用 $where 来比较文档中的两个字段,这似乎真的很慢。

我的查询如下所示:

db.mycollection.find({ $where : "this.lastCheckDate < this.modificationDate})

我想做的是在我的文档中添加一个字段,即isCheckDateLowerThenModDate,我可以在其上执行一个可能更快的查询:

db.mycollection.find({"isCheckDateLowerThenModDate":true})

我对 mongoDB 很陌生,不知道该怎么做。如果有人能给我一些提示或示例,我将不胜感激

  1. 如何在现有集合上初始化这样的字段
  2. 如何维护这个领域。这意味着如何在lastCheckDatemodificationDate更改时更新此字段。

在此先感谢您的帮助!

4

2 回答 2

1

你的想法是对的!

1.如何在现有集合上初始化这样的字段。

最简单的方法是加载每个文档(从您的语言),计算该字段,更新并保存。

或者您可以通过 mongo shell 执行更新:

db.mycollection.find().forEach(function(doc) { 
   if(doc.lastCheckDate < doc.modificationDate)
   {
     doc.isCheckDateLowerThenModDate = true;
   }
   else
   {
     doc.isCheckDateLowerThenModDate = false;
   }
   db.mycollection.save(doc); 
});

2.如何维护这个字段。这意味着当 lastCheckDate 或 modifyDate 更改时如何更新此字段。

您必须从您的客户端代码中自己完成。为更新、保存操作和每次重新计算这个值做一些包装。要绝对确定此更新有效 - 编写单元测试。

于 2012-08-30T09:03:47.440 回答
1

$where子句很慢,因为它使用 JavaScript 解释器评估每个文档。

有几种选择:

1)假设您的用例是“查找需要更新的记录”,请利用稀疏索引

  • 每当更新时添加一个布尔字段needsChecking,例如$setmodificationDate

  • 在您的“检查”过程中,找到设置了此字段的文档(由于索引稀疏,应该很快)

    db.mycollection.find({'needsChecking':true});

  • 在您完成所需的任何检查后,$unsetneedsChecking字段。

2) MongoDB 2.2 中一个新的(更快的)特性是聚合框架

下面是一个基于日期比较添加“isUpdated”字段,然后过滤匹配文档的示例:

    db.mycollection.aggregate(
            { $project: {
                    _id: 1,
                    name: 1,
                    type: 1,
                    modificationDate: 1,
                    lastCheckDate: 1,
                    isUpdated: { $gt:["$modificationDate","$lastCheckDate"] }
            }},
            { $match : {
                    isUpdated : true,
            }}
    )

当前使用聚合框架的一些注意事项是:

  • 您必须指定要包含的字段_id
  • 结果仅限于当前最大 BSON 文档大小(MongoDB 2.2 中为 16Mb)
于 2012-08-30T10:19:55.423 回答