我是MongoDB的初学者。 我使用的是3.2版。 我在几个地方读到MongoDB在查询中只能使用一个索引,但我发现的信息似乎有点过时,我在官方文档中找不到。
我收集了大约500M这种形式的产品:
{_id: ObjectId('574d92332a2b10d7618b4575'), title: A, category_id: ObjectId('574d92332a2b10d7618b4575'), price: 30.23, rating:5 },
{_id: ObjectId('574d92332a2b10d7618b4575'), title: B, category_id: ObjectId('574d92332a2b10d7618b4575'), price: 20.23, rating:3 },
{_id: ObjectId('574d92332a2b10d7618b4575'), title: C, category_id: ObjectId('574d92332a2b10d7618b4575'), price: 10.23, rating:4 }
我需要找到每个类别的所有产品,然后按价格排序,然后按价格排序,但最终用户可能还想直接按价格对其进行排序。
每个查询都需要传递category_id,这是冲动的。
我创建了3个索引:{category_id:1}
,{rating:1}
和{price:1}
。
这些查询很快:
每个类别最贵的产品
db.products.find({category_id:ObjectId('574d92332a2b10d7618b4575')}).sort({price:-1})
每个类别的最佳产品
db.products.find({category_id:ObjectId('574d92332a2b10d7618b4575')}).sort({rating:-1})
每个类别的最差产品
db.products.find({category_id:ObjectId('574d92332a2b10d7618b4575')}).sort({rating:1})
但是这个查询速度非常慢
每个类别的最佳产品,然后最便宜的
db.products.find({category_id:ObjectId('574d92332a2b10d7618b4575')}).sort({rating:-1, price:1})
如果你是我,你会创建哪些索引,为什么?
我开始认为单独使用price
和rating
是愚蠢的,因为每个查询都需要category_id
,所以我的索引可能包含category_id
,但是{{ 3}}
我已经what confuses me is the last paragraph of the official doc about compound indexes,但我找不到我的具体问题的答案。
答案 0 :(得分:1)
您应创建复合索引以满足您的查询,在大多数情况下,它们应包含您的查询字词和排序条件。
我认为您提到的令人困惑的段落是关于何时存在多个排序标准,例如:复合种类。当您进行复合排序时,索引条目的顺序和方向都很重要。如果您只按单个值排序,则索引的方向(1或-1,升序或降序)无关紧要。
有关详细信息和示例,请参阅this SO question。另一个很好的资源是这篇Optimizing Compound Indexes博客文章。
您可能需要考虑是否真的需要允许这样的复合排序,对于您的示例,从大多数电子商务网站看起来更常见,您只能按评级或价格排序,但不能同时排序。
答案 1 :(得分:0)
使用复合指数, Mongo在查询执行时只考虑一个索引并使用.explain(“executionStats”)来查看。
db.collection.find({your query}).explain("executionStats")
如果你执行上面的查询,你可以在result中找到“queryPlanner”对象,其中包含winsPlan(最终考虑索引)和rejectedPlan(最初被认为但不足以胜任的所有索引)的详细信息。 p>