如何使用sort索引$或查询

时间:2013-02-09 19:40:41

标签: mongodb

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

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

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

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

您可以采用以下选择性:

  • deleted - 99%
  • type - 25%
  • creator._idparent._idsomerelation._id - < 1%

4 个答案:

答案 0 :(得分:5)

现在,您需要为此查询提供多个索引;毫无疑问。

问题是索引

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

所以你知道$or会有一些排序的性能问题,并且将排序字段放入$or子句索引是无用的atm。

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

db.col.ensureIndex({type:-1,deleted:-1,date.created:-1})

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

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

因此,应该能够处理查询的主句。现在来处理那些$or s。

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

$or

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

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

答案 1 :(得分:3)

Mongodb每个查询只能使用一个索引,所以我看不到使用索引查询模型中someid的方法。

因此,最好的方法是为此任务添加特殊字段:

ids = [creator._id, parent._id, somerelation._id]

在这种情况下,您无需使用$or运算符即可查询:

db.things.find({
  deleted: false,
  type: 'thing',
  ids: someid
}).sort({
  'date.created': -1
})

在这种情况下,您的索引将如下所示:

{deleted:1, type:1, ids:1, 'date.created': -1}

答案 2 :(得分:1)

如果您可以灵活地调整架构,我建议添加一个新字段associatedIds:[],它将包含creator._id,parent._id,some relation._id - 您可以在更新时自动更新该字段主要的相应字段,但现在您可以在此字段上键入复合索引,键入和created_date,这样就完全无需$或查询。

答案 3 :(得分:0)

考虑到您对索引的要求,我建议您在$或查询旁边使用$ orderBy运算符。我的意思是你应该能够在$或查询中使用的$或表达式中的条件索引,然后你可以$ orderBy来对结果进行排序。

例如:

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

上述查询需要$或表达式中每个字段的复合索引以及orderBy条件中指定的排序对象。

例如:

db.things.ensureIndex{'parent._id': 1,"date.created":-1}
and so on for other fields.

最好为结果指定“limit”以防止mongodb执行大量的内存排序。 阅读更多$orderBy operator here