我熟悉大型MongoDB集合中基于范围的分页的最佳实践,但是我正在努力弄清楚如何对排序值在非唯一字段上的集合进行分页.
例如,我有大量的用户,并且有一个字段表示他们做过某些事情的次数.此字段绝对不是唯一的,并且可能具有大量具有相同值的文档.
我想返回按'numTimesDoneSomething'字段排序的结果.
这是一个示例数据集:
{_id: ObjectId("50c480d81ff137e805000003"), numTimesDoneSomething: 12}
{_id: ObjectId("50c480d81ff137e805000005"), numTimesDoneSomething: 9}
{_id: ObjectId("50c480d81ff137e805000006"), numTimesDoneSomething: 7}
{_id: ObjectId("50c480d81ff137e805000007"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000002"), numTimesDoneSomething: 15}
{_id: ObjectId("50c480d81ff137e805000008"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000009"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000004"), numTimesDoneSomething: 12}
{_id: ObjectId("50c480d81ff137e805000010"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000011"), numTimesDoneSomething: 1}
Run Code Online (Sandbox Code Playgroud)
如何返回按'numTimesDoneSomething'排序的数据集,每页有2条记录?
我已经搜索过,并没有找到问题的Go解决方案,没有使用或不使用mgo.v2,不是在StackOverflow而不是在任何其他网站上.此问答是本着知识共享/记录的精神.
假设我们users在MongoDB中有一个使用此Go建模的集合struct:
type User struct {
ID bson.ObjectId `bson:"_id"`
Name string `bson:"name"`
Country string `bson:"country"`
}
Run Code Online (Sandbox Code Playgroud)
我们希望根据某些条件对用户进行排序和列出,但由于预期的长结果列表而实施了分页.
为了实现某些查询的结果的分页,MongoDB的和mgo.v2驱动包内置了支持的形式Query.Skip()和Query.Limit(),例如:
session, err := mgo.Dial(url) // Acquire Mongo session, handle error!
c := session.DB("").C("users")
q := c.Find(bson.M{"country" : "USA"}).Sort("name", "_id").Limit(10)
// To get the nth page:
q = q.Skip((n-1)*10)
var users []*User
err = q.All(&users)
Run Code Online (Sandbox Code Playgroud)
然而,如果页面数量增加,这会变慢,因为MongoDB不能"神奇地"跳转到结果中的第x 个文档,它必须遍历所有结果文档并省略(不返回)x需要的第一个文档.跳过.
MongoDB提供了正确的解决方案:如果查询对索引进行操作(它必须处理索引),cursor.min()则可以使用指定第一个索引条目来开始列出结果.
这个Stack Overflow答案展示了如何使用mongo客户端完成它:如何使用MongoDB中的范围查询进行分页?
注意:上述查询所需的索引是: …
假设一个包含3个字段的假设文档:
现在,给定一个关于emailAddress和帐户的查询,以下两个索引中的哪一个将表现更好: