mgocursorpagination

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 11, 2019 License: MIT Imports: 7 Imported by: 0

README

CircleCI Test Coverage GoDoc

mongocursorpagination

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.

mongocursorpagination 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...

mongocursorpagination 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 mongocursorpagination:

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

// 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.

Documentation

Overview

Package mgocursorpagination eases the computation of pagination information of a find mongo query by augmenting the base query with cursor information and returning a cursor.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cursor

type Cursor struct {
	// The URL safe previous page cursor to pass in a Find call to get the previous page.
	// This is set to the empty string if there is no previous page.
	Previous string
	// The URL safe next page cursor to pass in a Find call to get the next page.
	// This is set to the empty string if there is no next page.
	Next string
	// true if there is a previous page, false otherwise
	HasPrevious bool
	// true if there is a next page, false otherwise
	HasNext bool
	// Total count of documents matching filter - only computed if CountTotal is True
	Count int
}

Cursor holds the pagination data about the find mongo query that was performed.

func Find

func Find(p FindParams, results interface{}) (Cursor, error)

Find executes a find mongo query by using the provided FindParams, fills the passed in result slice pointer and returns a Cursor.

type FindParams

type FindParams struct {
	// The mongo database to use
	DB *mgo.Database
	// The name of the mongo collection to query
	CollectionName string
	// The find query to augment with pagination
	Query bson.M
	// The number of results to fetch, should be > 0
	Limit int
	// true, if the results should be sort ascending, false otherwise
	SortAscending bool
	// The name of the mongo collection field being paginated and sorted on. This field must:
	// 1. Be orderable. We must sort by this value. If duplicate values for paginatedField field
	//    exist, the results will be secondarily ordered by the _id
	// 2. Be indexed. For large collections, this should be indexed for query performance
	// 3. Be immutable. If the value changes between paged queries, it could appear twice
	// 4. Match the bson field name the result struct. e.g.:
	//
	//    PaginatedField would be "name" when paginating employees by name
	//
	//    type Employee struct {
	//        ID          bson.ObjectId `bson:"_id"`
	//        Name        string        `bson:"name"`
	//    }
	//
	PaginatedField string
	// The collation to use for the sort ordering.
	// See https://docs.mongodb.com/manual/reference/collation-locales-defaults/#supported-languages-and-locales
	// This is ignored if PaginatedField is empty
	Collation *mgo.Collation
	// The value to start querying the page
	Next string
	// The value to start querying previous page
	Previous string
	// Whether or not to include total count of documents matching filter in the cursor
	// Specifying true makes an additionnal query
	CountTotal bool
}

FindParams holds the parameters to be used in a paginated find mongo query that will return a Cursor.

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL