@@ -65,6 +65,7 @@ use uuid::Uuid;
6565use crate :: cas_utils:: is_zero_digest;
6666use crate :: redis_utils:: {
6767 FtAggregateCursor , FtAggregateOptions , FtCreateOptions , SearchSchema , ft_aggregate, ft_create,
68+ ft_search_count,
6869} ;
6970
7071/// The default size of the read chunk when reading data from Redis.
@@ -1632,7 +1633,80 @@ where
16321633 where
16331634 K : SchedulerIndexProvider + Send ,
16341635 {
1635- Err ( make_err ! ( Code :: Unimplemented , "Not implemented" ) )
1636+ if index. is_empty ( ) {
1637+ return Ok ( Vec :: new ( ) ) ;
1638+ }
1639+ let index_name = format ! (
1640+ "{}" ,
1641+ get_index_name!( K :: KEY_PREFIX , K :: INDEX_NAME , K :: MAYBE_SORT_KEY )
1642+ ) ;
1643+ let mut counts = Vec :: with_capacity ( index. len ( ) ) ;
1644+ for idx in index {
1645+ let index_value = idx. index_value ( ) ;
1646+ let sanitized_field = try_sanitize ( index_value. as_ref ( ) ) . err_tip ( || {
1647+ format ! ( "In RedisStore::count_by_index::try_sanitize - {index_value:?}" )
1648+ } ) ?;
1649+ let query = if sanitized_field. is_empty ( ) {
1650+ "*" . to_string ( )
1651+ } else {
1652+ format ! ( "@{}:{{ {} }}" , K :: INDEX_NAME , sanitized_field)
1653+ } ;
1654+ let run_ft_search = || {
1655+ Ok :: < _ , Error > ( async {
1656+ let mut client = self . get_client ( ) . await ?;
1657+ ft_search_count (
1658+ & mut client. connection_manager ,
1659+ index_name. as_str ( ) ,
1660+ query. as_str ( ) ,
1661+ )
1662+ . await
1663+ } )
1664+ } ;
1665+ let count = run_ft_search ( ) ?
1666+ . or_else ( |_| async {
1667+ let mut schema = vec ! [ SearchSchema {
1668+ field_name: K :: INDEX_NAME . into( ) ,
1669+ sortable: false ,
1670+ } ] ;
1671+ if let Some ( sort_key) = K :: MAYBE_SORT_KEY {
1672+ schema. push ( SearchSchema {
1673+ field_name : sort_key. into ( ) ,
1674+ sortable : true ,
1675+ } ) ;
1676+ }
1677+ let create_result = ft_create (
1678+ self . connection_manager . get_connection ( ) . await ?. 0 ,
1679+ format ! (
1680+ "{}" ,
1681+ get_index_name!( K :: KEY_PREFIX , K :: INDEX_NAME , K :: MAYBE_SORT_KEY )
1682+ ) ,
1683+ FtCreateOptions {
1684+ prefixes : vec ! [ K :: KEY_PREFIX . into( ) ] ,
1685+ nohl : true ,
1686+ nofields : true ,
1687+ nofreqs : true ,
1688+ nooffsets : true ,
1689+ temporary : Some ( INDEX_TTL_S ) ,
1690+ } ,
1691+ schema,
1692+ )
1693+ . await
1694+ . err_tip ( || {
1695+ format ! (
1696+ "Error with ft_create in RedisStore::count_by_index({index_name})" ,
1697+ )
1698+ } ) ;
1699+ let count_result = run_ft_search ( ) ?. await . err_tip ( || {
1700+ format ! (
1701+ "Error with second FT.SEARCH count in RedisStore::count_by_index({index_name})" ,
1702+ )
1703+ } ) ;
1704+ count_result. or_else ( |e| create_result. merge ( Err ( e) ) )
1705+ } )
1706+ . await ?;
1707+ counts. push ( count) ;
1708+ }
1709+ Ok ( counts)
16361710 }
16371711
16381712 async fn search_by_index_prefix < K > (
0 commit comments