如何使用sort索引$或查询

Jon*_*Ong 6 mongodb

假设我的查询看起来像这样:

db.things.find({
  deleted: false,
  type: 'thing',
  $or: [{
    'creator._id': someid
  }, {
    'parent._id': someid
  }, {
    'somerelation._id': someid
  }]
}).sort({
  'date.created': -1
})
Run Code Online (Sandbox Code Playgroud)

也就是说,我想找到符合这三个条件之一的文档,并按最新的顺序排序.但是,$或查询在与排序一起使用时不会并行使用索引.那么,我该如何索引这个查询呢?

http://docs.mongodb.org/manual/core/indexes/#index-behaviors-and-limitations

您可以采用以下选择性:

  • deleted - 99%
  • type - 25%
  • creator._id,parent._id,somerelation._id- <1%

Sam*_*aye 5

现在,您将需要多个索引来进行此查询; 毫无疑问.

问题是什么索引

现在您必须考虑到$or由于MongoDBs查询优化器中的错误,您的所有人都无法使用索引以最佳方式对数据卡进行排序:https://jira.mongodb.org/browse/SERVER- 1205.

因此,您知道$or将在排序中存在一些性能问题,并且将排序字段放入$or子句索引中是无用的atm.

因此,考虑到这一点,您想要的第一个索引是涵盖您正在进行的基本查询的索引.正如@Leonid所说,你可以将它变成一个复合索引,但是,我不会按照他所做的顺序这样做.相反,我会这样做:

db.col.ensureIndex({type:-1,deleted:-1,date.created:-1})
Run Code Online (Sandbox Code Playgroud)

deleted由于其超低选择性,我对该指数领域完全不确定; 事实上,它可能会创建一个性能较低的操作(对大多数数据库来说都是如此),包括SQL在索引中,而不是被取出.这部分需要你测试; 也许这个领域应该是最后一个(?).

至于索引的顺序,我刚刚猜到了.我已经说过所有领域的DESC,因为你的类型是DESC,但你需要explain自己在这里.

所以应该能够处理查询的主句.现在来处理那些$or.

每个都$or将单独使用一个索引,MongoDB查询优化器也会单独查找它们的索引,就像它们完全是单独的查询一样,所以值得注意的是复合索引的一些小问题(http://docs.mongodb.org)/manual/core/indexes/#compound-indexes)是他们在前缀上工作的(这里有一个例子说明:http://docs.mongodb.org/manual/core/indexes/#id5)所以你不能制作一个单个复合索引覆盖所有三个子句,因此在$or(考虑上面的错误)上声明索引的更优化方法是:

db.col.ensureindex({creator._id:1});
db.col.ensureindex({aprent._id:1});
db.col.ensureindex({somrelation._id:1});
Run Code Online (Sandbox Code Playgroud)

它应该能够让您开始为查询创建最佳索引.

但是我应该强调你需要自己测试一下.