minquery icon indicating copy to clipboard operation
minquery copied to clipboard

Return Page Count and Current Page

Open tutley opened this issue 7 years ago • 5 comments

There may already be a way to deduce this from the cursor, I'm not sure, but it would be really nice if the minquery.All function would also return some meta-data about the result set such as the total number of pages matching the query criteria along with the current page that is represented in the returned slice of results. This can be accomplished currently by running a second mgo.Find to simply count the data set, and to pass the current page number back and forth with the client, but that seems "ugly". Maybe there's already a better way to do that, I don't know.

tutley avatar Nov 05 '17 01:11 tutley

The total number of documents matching the query can only be determined by a separate query, and the current page count cannot be acquired from the cursor. The cursor only holds info about the last (or next) index entry, the page count must be maintained separately.

You may choose to extend the cursor with these info yourself. An easy way would be something like this conceptually:

type MyCursor struct {
	Cursor string // original cursor
	Page   int    // current page count
	Total  int    // Total items matching the query, or you may use it to a max page value
}

And simply populate and encode a value of MyCursor, and transmit that as your cursor.

icza avatar Nov 05 '17 06:11 icza

@tutley care to share how this was finally sloved? @icza any chance you go provide more code on how to extend the cursor like you suggested above.

e.g show how to use the new MyCursor struct above

montera82 avatar May 07 '18 15:05 montera82

For example, let's say you fetch the first page:

total := /* query total count, something like c.Find(query).Count() */
q := /* ... */ // q is a MinQuery
newCursor, err := q.All( /*params*/ )

myc := MyCursor{Cursor: newCursor, Page: 1, Total: total}
// Encode myc, and send that to the client.
// Encode it however you like, e.g. json.Marsha(), followed by base64.RawURLEncoding.EncodeToString()

encCurs := ...

And when the client requests the 2nd page, he sends the encCurs:

// Decode cursor:
myc := /* Decoded cursor, reverse order: base decode, then json.Unmarshal() */

// You may use myc.Cursor to pass to MinQuery
// Get NextPage:
newCursor, err := q.All( /*params*/ )

// Create new cursor:
myc.Cursor = newCursor
myc.Page++

// Do the same cursor encoding, and send this new cursor to the client

icza avatar May 11 '18 09:05 icza

Im getting an error "planner returned error: unable to find relevant index for max/min query" when trying to access the 2nd page. my code: `q := minquery.New(db, "user", bson.M{}).Sort("nick", "_id").Limit(2)

newCursor1, _ := q.All(&userList, "prn", "nick", "_id")
for _, user := range userList {
	log.Print("ID:" + user.ID)
}
log.Print("\nFirst cursor:" + newCursor1)

if cursor := newCursor1; cursor != "" {
	q = q.Cursor(cursor)
}

newCursor2, err := q.All(&userList, "prn", "nick", "_id")
for _, user := range userList {
	log.Print("ID:" + user.ID)
}
if err != nil {
	log.Print(err)
}
log.Print("\nnew cursor:" + newCursor2)`

sirinibin avatar Nov 23 '18 22:11 sirinibin

Your error message says no relevant index found. What indices do you have?

icza avatar Nov 24 '18 09:11 icza