如何将字段添加到包含两个其他字段的比较结果的文档

时间:2012-08-30 08:32:26

标签: mongodb

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

我的查询如下:

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

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

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

我对mongoDB很新,不知道怎么做。如果有人能给我一些提示或示例

,我将不胜感激
  1. 如何在现有集合中初始化此类字段
  2. 如何维护此字段。这意味着在lastCheckDatemodificationDate更改时如何更新此字段。
  3. 提前感谢您的帮助!

2 个答案:

答案 0 :(得分: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或modificationDate更改。

您必须自己从客户端代码中执行此操作。制作一些包装器以进行更新,保存操作并每次重新计算此值。要确保此更新有效 - 请编写单元测试。

答案 1 :(得分:1)

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

有几种选择:

1)假设您的用例是“查找需要更新的记录”,请利用sparse index

  • 每当needsChecking更新时,都会添加modificationDate$set这样的布尔字段

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

      

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

  • 完成所需的检查后,$unset needsChecking字段。

2)MongoDB 2.2中的一个新的(更快的)功能是Aggregation Framework

以下是根据日期比较添加“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)