Skip to content

diptanw/mongocursorpagination

 
 

Repository files navigation

CircleCI Test Coverage GoDoc

mgocursorpagination

A go package for the mgo mongo driver (globalsign/mgo) which ports the find functionality offered by the node.js mongo-cursor-pagination module. Also inspired by icza/minquery.

mgocursorpagination helps implementing cursor based pagination in your mongodb backed service:

...where an API passes back a "cursor" (an opaque string) to tell the caller where to query the next or previous pages. The cursor is usually passed using query parameters next and previous...

mgocursorpagination helps by providing a function that make it easy to query within a Mongo collection and returning a url-safe string that you can return with your HTTP response.

Example

For this example we will be using an items mongo collection where items look like this:

Item struct {
    ID        bson.ObjectId `bson:"_id"`
    Name      string        `bson:"name"`
    CreatedAt time.Time     `bson:"createdAt"`
}

Where the items collection is indexed:

mgo.Index{
    Name: "cover_find_by_name",
    Key: []string{
        "name",
    },
    Unique: false,
    Collation: &mgo.Collation{
        Locale:   "en",
        Strength: 3,
    },
    Background: true,
}

The items store offers a method to find items (e.g. by name) and paginate the results using the find function exposed by mgocursorpagination:

import "github.com/qlik-oss/mgocursorpagination"
...

// Find returns paginated items from the database matching the provided query
func (m *mongoStore) Find(query bson.M, next string, previous string, limit int, sortAscending bool, paginatedField string, collation mgo.Collation) ([]Item, mgocursor.Cursor, error) {
	fp := mgocursor.FindParams{
        Collection:     m.col,
		Query:          query,
		Limit:          limit,
		SortAscending:  sortAscending,
		PaginatedField: paginatedField,
		Collation:      &collation,
		Next:           next,
		Previous:       previous,
		CountTotal:     true,
	}
	var items []Item
	c, err := mgocursor.Find(fp, &items)
	cursor := mgocursor.Cursor{
		Previous:    c.Previous,
		Next:        c.Next,
		HasPrevious: c.HasPrevious,
		HasNext:     c.HasNext,
	}
	return items, cursor, err
}

Assuming there are 4 items in the collection that have the name "test item n", we can then get the first page of results sorted by name by calling the items store's find method:

searchQuery := bson.M{"name": bson.RegEx{Pattern: "test item.*", Options: "i"}}
englishCollation := mgo.Collation{Locale: "en", Strength: 3}

// Arguments: query, next, previous, limit, sortAsc, paginatedField, collation
foundItems, cursor, err := store.Find(searchQuery, "", "", 2, true, "name", englishCollation)

To get the next page:

// Arguments: query, next, previous, limit, sortAsc, paginatedField, collation
foundItems, cursor, err = store.Find(searchQuery, cursor.Next, "", 2, true, "name", englishCollation)

from the second page, we can get to first page:

// Arguments: query, next, previous, limit, sortAsc, paginatedField, collation
foundItems, cursor, err = store.Find(searchQuery, "", cursor.Previous, 2, true, "name", englishCollation)

See items_store_test.go for the integration test that uses the items store's find method.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 93.8%
  • Shell 4.2%
  • Makefile 2.0%