Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pageable query and return the pageable results with total count.... #39

Open
GiKyouGetsu opened this issue Dec 14, 2023 · 7 comments

Comments

@GiKyouGetsu
Copy link

For the pageable query, is there any way to return the affect rows for specific offset and limit count, and with the total rows for the specific query condition...

@horacimacias
Copy link
Collaborator

can you provide an example of the type of query you're trying to execute? some equivalent curl or dump of a manual request/response would help.

@GiKyouGetsu
Copy link
Author

I have a such typed couch DB
{ "_id": "0f8232dece845fdb63cde44c270034c0", "_rev": "1-e6508133c66517d738a637acb856b4dd", "customer_crm_id": "customeridwei41", "customer_id": "85cdfc9c-7145-4fb6-b3f3-942852f7a5a9", "identifiers": [ { "identifierType": "EMAIL_ADDRESS", "identifierValue": "wei41@xxxxx.com" } ], "customer_level": "VIP", "tags": [], "create_datetime": "2023-12-12T09:39:37.442", "update_datetime": "2023-12-12T09:39:37.442" }
, I use the funcitoin : db.find::(&query):
The query is same like:
let query_json = json!({ "selector": { "identifiers": { "$elemMatch": { "identifierType": { "$eq": r#type }, "identifierValue": { "$eq": value } } } }, "sort": [] })
let query = FindQuery::new_from_value(query_json)
.limit(limit_size)
.skip((page_num - 1) * limit_size)
.sort(vec![SortSpec::Complex(sort)])

The result is the struct:
pub struct DocumentCollection<T: TypedCouchDocument> { pub offset: Option<u32>, pub rows: Vec<T>, pub total_rows: u32, pub bookmark: Option<String>, }

the field "total_rows" is just the affect rows instead of total rows that match the query condition

how can I get the total rows for this typed query?

@horacimacias
Copy link
Collaborator

sorry but I'm still not sure I understand. Are you able to run the query using CouchDB's Fauxton or curl directly and you get the total rows? If so, can you provide such a query?

I see you're using FindQuery's limit and skip; isn't the issue that you're skipping and limiting but at the same time you're trying to get the total rows that match the query condition?

All in all, I'm not sure if the question is more a CouchDB usage question or something related to couch-rs.
If you provide more information I may be able to help either way.

@GiKyouGetsu
Copy link
Author

GiKyouGetsu commented Dec 18, 2023

Actually, my question is related to couch-rs usage.

Which function in couch-rs can return the pageable results with the total records (total records means that the count of match the conditions instead of current page's total) ?

@horacimacias
Copy link
Collaborator

If you were using views, I think you'd want to check about reduce operations, specifically _count:

https://docs.couchdb.org/en/stable/ddocs/views/intro.html
https://docs.couchdb.org/en/stable/ddocs/ddocs.html#count

if you run the query without skip and limit (and you don't need to sort either if you just want to get the count), combined with using reduce: _count, you should get the total number of rows that match that query.

...but you're using _find which does not support reduce operations yet:
apache/couchdb#1323
apache/couchdb#1254

I think you then want to check the bookmark parameter. There is also some more information about pagination use cases:
https://docs.couchdb.org/en/stable/api/database/find.html
https://docs.couchdb.org/en/stable/api/database/find.html#pagination

@GiKyouGetsu
Copy link
Author

If I use couch-rs to invoke the views, which function can meet my requirement?

@hmacias-avaya
Copy link
Contributor

looking at your query selector:

{ "identifiers": { "$elemMatch": { "identifierType": { "$eq": r#type }, "identifierValue": { "$eq": value } }

although you could use views, I don't think you want to as your query is dynamic. You will not want to have a view for every possible query selector value.
All in all, if you want to get the count of how many entries match a certain query, you can use the bookmark parameter I already mentioned.
You send your first query, without sort. You can use a limit that is a good compromise between number of queries you'll have to do and size of each query.

{
    "selector": {
        "identifiers": {
            "$elemMatch": {
                "identifierType": {
                    "$eq": "EMAIL_ADDRESS"
                },
                "identifierValue": {
                    "$eq": "wei41@xxxxx.com"
                }
            }
        }
    },
    "limit": 40
}

The response will contain a bookmark parameter:

{
    "docs": [
...
    ],
    "bookmark": "g1AAAABweJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGBhZGicZpRkkJ1qam5qbpFiYGZuZm6YZJaYYGJqnmJiC9HHA9BGlIwsAdSsdXw",
}

Then you want to use a loop so that the request is repeated, using the last received bookmark, as long as the number of items in docs equal to the limit you sent (if you said limit 40 and received 5 docs, you know there is no "next page").

Basically you're executing requests for all the pages until you get to the end and you know the total number of entries.

If you only care about counting, and you don't want to look at the row data, you can also use the fields parameter to tell couchdb to only send back certain fields, for example fields:["_id"] since you know you don't want to read the object anyway. This will avoid sending the full object that you are not going to use anyway.

If you want to count and also get the row data, then you do want to get all fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants