【发布时间】:2017-02-16 15:13:15
【问题描述】:
假设我有一个包含如下文档的 MongoDB 集合:
{ "_id": ObjectId("the_object_id"),
"type": "BLOG_POST",
"state": "IN_PROGRESS",
"createDate":ISODate("2017-02-15T01:01:01.000Z"),
"users": {
"posted": ["user1", "user2", "user3"],
"favorited": ["user1", "user4", "user5", "user6"],
"other_fields": "other data",
},
"many_more_fields": "a bunch of other data"
}
我有一个这样的查询:
db.collection.find({"$and":[
{"type": "BLOG_POST"},
{"$or": [ {"users.posted":"userX"}, {"users.favorited":"userX"} ] },
{"state": {"$ne":"COMPLETED"}}
]}).sort({"createDate":1})
该集合目前仅在 _id 字段上具有索引,并且某些字段未包含在此查询或示例中。
就基数而言,文档包含: type=BLOG_POST 大约是集合的 75%,状态 $ne "COMPLETED" 大约是集合的 50%,用户在 users.posted 或 users.favorited 中最多占集合的 2%。
对于这个用例,最好的索引或索引集是什么?
据我了解,我们不能在同一个索引中同时索引 users.posted 和 users.favorited,因为它们都是数组。将来我们可能会创建一个新的 users.userswhocare 数组,它是两个字段的集合,但假设我们不能在短期内做出改变。
我还认为 state 上的 $ne 意味着通常不会使用 state 上的索引。查询规划器是否能够通过索引末尾的 state 字段来处理 $ne 条件?
我有一个索引 {"type":1, "createDate":1, "state":1} 的想法,以便查询会命中类型,使用 createDate 进行排序,并处理$ne 与索引的最后一位。它仍然需要提取 35%-40% 的文档来为用户进行测试。不好,但比当前的集合扫描有所改进。
或者,我可以创建两个索引,一个像 {"users.posted":1, "type":1, "createDate":1, "state":1} 和 {"users.favorited":1, "类型”:1,“创建日期”:1,“状态”:1}。 查询规划器是否会使用这两个索引的交集来更快地找到感兴趣的文档?
我们目前使用的是 MongoDB 3.2.5。如果 MongoDB 3.2 和 3.4 之间的答案存在差异,我很想知道它们。
【问题讨论】:
标签: mongodb mongodb-query mongodb-indexes