2

假设我有一个看起来像这样的文档:

{
  _id: ObjectId("5260ca3a1606ed3e76bf3835"),
  event_id: "20131020_NFL_SF_TEN",
  team: {
    away: "SF",
    home: "TEN"
  }
}

我想查询任何以“SF”作为客队或主队的比赛。所以我放了一个索引team.awayteam.home运行一个 $or 查询来查找所有旧金山的比赛。

另外的选择:

{
  _id: ObjectId("5260ca3a1606ed3e76bf3835"),
  event_id: "20131020_NFL_SF_TEN",
  team: [
    {
      name: "SF",
      loc: "AWAY"
    },
    {
      name: "TEN",
      loc: "HOME"
    }
  ]
}

在上面的数组中,我可以放置一个索引,team.name而不是像以前那样放置两个索引。然后我会查询team.name里面有“SF”的任何游戏。

哪个查询会更有效?谢谢!

4

1 回答 1

2

我相信您会希望使用您给出的第二个示例,其中包含team.name.

与操作员合作时,您需要了解一些特殊注意事项$or。引用文档(带有一些额外的格式):

在查询中使用索引时$or,请记住查询的每个子句$or将并行执行。这些子句可以各自使用自己的索引。

db.inventory.find ( { $or: [ { price: 1.99 }, { sale: true } ] } )

对于此查询,您将在 price: 上创建一个索引db.inventory.ensureIndex({ price: 1 }
并在 sale: 上创建另一个索引,db.inventory.ensureIndex({ sale: 1 } )
而不是复合索引。

考虑到您的第一个示例,索引您不打算专门查询的字段没有多大意义。当您说您不介意SF是在客场比赛还是主场比赛时,您总是会在查询中同时包含 theaway home字段,因此您使用了两个索引,您只需要查询一个值 - SF


在这个阶段似乎应该提到,在考虑文档格式时,您应该始终考虑大多数查询。考虑您计划最常进行的查询并相应地构建您的文档。最好尽可能处理 80% 的情况,而不是尝试解决所有可能性(这可能会导致整体性能下降)。


正如您所说,查看您的第二个嵌套文档示例,您只需要使用一个索引(节省服务器上的宝贵空间)。

$or文档中一些更相关的引用(再次添加了格式):

此外,当在查询中使用$or带有sort()方法的运算符时,查询将不会使用$or字段上的索引。考虑以下查询,它sort()为上述查询添加了一个方法:

db.inventory.find ({ $or: [{ price: 1.99 }, { sale: true }] }).sort({item:1})

此修改后的查询将不使用索引 onprice也不使用索引 on sale

所以现在的问题是——你打算使用这个sort()功能吗?如果答案是肯定的,那么您应该意识到您的索引可能会变得毫无用处!:(


从中得出的结论几乎是“取决于!”。考虑您计划进行的查询,并根据您的使用预测考虑哪些文档结构和索引对您最有利。

于 2013-10-20T21:36:00.020 回答