Open GiKyouGetsu opened 9 months ago
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.
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::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?
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.
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) ?
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: https://github.com/apache/couchdb/issues/1323 https://github.com/apache/couchdb/issues/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
If I use couch-rs to invoke the views, which function can meet my requirement?
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.
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...