15

I'm trying to execute a query with "sort" and "limit". With mgo you could do Find(nil).Sort(“-when”).Limit(10) but the new, official mongo driver has no such methods. How can I sort and "limit" with the new driver?

1
  • 2
    Presumably you'd use findopt.Sort to build options for Find. Unfortunately, it takes an interface{} argument, the documentation says nothing useful, and there are no examples in the documentation or GitHub. Commented Jul 4, 2018 at 20:11

6 Answers 6

27

In the current version mongo-go-driver v1.0.3, the options are simplified. For example to perform find, sort and limit:

import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

options := options.Find()

// Sort by `_id` field descending
options.SetSort(bson.D{{"_id", -1}})

// Limit by 10 documents only 
options.SetLimit(10)

cursor, err := collection.Find(context.Background(), bson.D{}, options)

See more available options on godoc.org/go.mongodb.org/mongo-driver/mongo/options. Especially FindOptions for all possible options for Find().

Sign up to request clarification or add additional context in comments.

Comments

5

The official driver is not straightforward as mgo. You can do sort and limit using the findopt.Limit and findopt.Sort.

You can see examples from the official repository.

https://github.com/mongodb/mongo-go-driver/blob/5fea1444e52844a15513c0d9490327b2bd89ed7c/mongo/crud_spec_test.go#L364

2 Comments

Not being straightforward is an understatement. It's total rubbish
This one is deprecated. Use options.Find() instead.
5

You can use

findOptions := options.Find()
findOptions.SetLimit(2)
findOptions.SetSkip(2)
...
cursor, err := collection.Find(context.Background(), bson.M{}, findOptions)

resource at https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial

Comments

5

you need import "github.com/mongodb/mongo-go-driver/options" package to build a findOptions.

import github.com/mongodb/mongo-go-driver/options

findOptions := options.Find() // build a `findOptions`
findOptions.SetSort(map[string]int{"when": -1}) // reverse order by `when`
findOptions.SetSkip(0) // skip whatever you want, like `offset` clause in mysql
findOptions.SetLimit(10) // like `limit` clause in mysql

// apply findOptions
cur, err := collection.Find(context.TODO(), bson.D{}, findOptions)
// resolve err

for cur.Next(context.TODO()) {
   // call cur.Decode()
}

Comments

3

The sort-option apparently requires you to add a map[string]interface{} where you can specify a field as key and a sortOrder as value (where 1 means ascending and -1 means descending) as following:

sortMap := make(map[string]interface{})
sortMap["version"] = 1
opt := findopt.Sort(sortMap)

As far as I can see this means that you are only able to properly sort results by one sortField because keys in a go map are stored in a random order.

Comments

3

ONE LINE OPTION

I know there is already a lot of answers but you can do it as one line (if you need it for any case of yours)

// From the Doc
// func (f *FindOptions) SetSort(sort interface{}) *FindOptions

cursor, err := collection.Find(context.Background(), bson.M{}, options.Find().SetSort(map[string]int{"when": -1}).SetLimit(10))

SetSort() and the others currently returns the parent pointer itself

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.