我想加快对我的mongoDB的查询,该查询使用$ where来比较文档中的两个字段,这似乎非常慢。
我的查询如下:
db.mycollection.find({ $where : "this.lastCheckDate < this.modificationDate})
我想要做的是在我的文档中添加一个字段,即isCheckDateLowerThenModDate
,我可以在其上执行一个更快的查询:
db.mycollection.find({"isCheckDateLowerThenModDate":true})
我对mongoDB很新,不知道怎么做。如果有人能给我一些提示或示例
,我将不胜感激lastCheckDate
或modificationDate
更改时如何更新此字段。 提前感谢您的帮助!
答案 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