我想分享我在MongoDB 3.0上遇到的问题/修复:
我使用的是MongoDB 2.4并在数据库上执行了以下查询:
假设:
查询1:
db.getCollection('myCollection').aggregate([
{ $match: { key1: "Value_for_Key1", key2: "Value_for_Key2", key3: "Value_for_Key3" , key4: { $exists: false }, key5 : 0 } },
{ $sort: { _id: 1 } },
{ $group: { _id: { key1: "$key1", key2: "$key2", key3: "$key3", key5: "$key5" }, latestValue: { $last: "$key6" }, id: { $last: "$_id" } } },
{ $project: { latestValue: "$latestValue", key1: "$_id.key1", key2: "$_id.key2", key3: "$_id.key3", key5: "$_id.key5" } }
])
要说出来:我想使用由(key1,key2,key3,key5)组成的组来获取最近创建的“key6”值(基于增量_id)
我的第一个性能问题是$ match阶段,它没有使用我的{key1,key2,key3}索引。所以,为了解决这个问题,我分成了两个阶段并且工作得很好:
db.getCollection('myCollection').aggregate([
{ $match: { key1: "Value_for_Key1", key2: "Value_for_Key2", key3: "Value_for_Key3" } },
{ $match: { key4: { $exists: false }, key5 : 0 } },
{ $sort: { _id: 1 } },
{ $group: { _id: { key1: "$key1", key2: "$key2", key3: "$key3", key5: "$key5" }, latestValue: { $last: "$key6" }, id: { $last: "$_id" } } },
{ $project: { latestValue: "$latestValue", key1: "$_id.key1", key2: "$_id.key2", key3: "$_id.key3", key5: "$_id.key5" } }
])
但是现在我迁移到了MongoDB 3.0,上面的查询又出现了性能问题。
在这个MongoDB版本中,他们实现了一个优化(here),它将我的$ match组合成一个,但由于某种原因,它没有像以前那样使用我的索引。
当我在$ match和$ sort之间添加一个虚拟的$ project阶段(我称之为虚拟,因为我只是在预测所有键)时,它修复了问题:
db.getCollection('myCollection').aggregate([
{ $match: { key1: "Value_for_Key1", key2: "Value_for_Key2", key3: "Value_for_Key3", key4: { $exists: false }, key5 : 0 } },
{ $project: { _id : "$_id", key1: "$key1", key2: "$key2", key3: "$key3", key5: "$key5", key6: "$key6" } },
{ $sort: { _id: 1 } },
{ $group: { _id: { key1: "$key1", key2: "$key2", key3: "$key3", key5: "$key5" }, latestValue: { $last: "$key6" }, id: { $last: "$_id" } } },
{ $project: { latestValue: "$latestValue", key1: "$_id.key1", key2: "$_id.key2", key3: "$_id.key3", key5: "$_id.key5" } }
])
所以,我没有找到任何关于MongoDB的文档,说$ $匹配后的$ sort可能会影响索引的使用。有人知道吗?