17
17
)
18
18
19
19
if TYPE_CHECKING :
20
+ from redis .commands .search .aggregation import AggregateResult
20
21
from redis .commands .search .document import Document
21
22
from redis .commands .search .result import Result
22
23
from redisvl .query .query import BaseQuery
25
26
import redis .asyncio as aredis
26
27
from redis .commands .search .indexDefinition import IndexDefinition
27
28
28
- from redisvl .exceptions import RedisModuleVersionError
29
+ from redisvl .exceptions import RedisModuleVersionError , RedisSearchError
29
30
from redisvl .index .storage import BaseStorage , HashStorage , JsonStorage
30
31
from redisvl .query import BaseQuery , CountQuery , FilterQuery
31
32
from redisvl .query .filter import FilterExpression
@@ -123,36 +124,6 @@ async def wrapper(self, *args, **kwargs):
123
124
return decorator
124
125
125
126
126
- def check_index_exists ():
127
- def decorator (func ):
128
- @wraps (func )
129
- def wrapper (self , * args , ** kwargs ):
130
- if not self .exists ():
131
- raise RuntimeError (
132
- f"Index has not been created. Must be created before calling { func .__name__ } "
133
- )
134
- return func (self , * args , ** kwargs )
135
-
136
- return wrapper
137
-
138
- return decorator
139
-
140
-
141
- def check_async_index_exists ():
142
- def decorator (func ):
143
- @wraps (func )
144
- async def wrapper (self , * args , ** kwargs ):
145
- if not await self .exists ():
146
- raise ValueError (
147
- f"Index has not been created. Must be created before calling { func .__name__ } "
148
- )
149
- return await func (self , * args , ** kwargs )
150
-
151
- return wrapper
152
-
153
- return decorator
154
-
155
-
156
127
class BaseSearchIndex :
157
128
"""Base search engine class"""
158
129
@@ -486,7 +457,6 @@ def create(self, overwrite: bool = False, drop: bool = False) -> None:
486
457
logger .exception ("Error while trying to create the index" )
487
458
raise
488
459
489
- @check_index_exists ()
490
460
def delete (self , drop : bool = True ):
491
461
"""Delete the search index while optionally dropping all keys associated
492
462
with the index.
@@ -502,8 +472,8 @@ def delete(self, drop: bool = True):
502
472
self ._redis_client .ft (self .schema .index .name ).dropindex ( # type: ignore
503
473
delete_documents = drop
504
474
)
505
- except :
506
- logger . exception ( "Error while deleting index" )
475
+ except Exception as e :
476
+ raise RedisSearchError ( f "Error while deleting index: { str ( e ) } " ) from e
507
477
508
478
def clear (self ) -> int :
509
479
"""Clear all keys in Redis associated with the index, leaving the index
@@ -629,13 +599,29 @@ def fetch(self, id: str) -> Optional[Dict[str, Any]]:
629
599
return convert_bytes (obj [0 ])
630
600
return None
631
601
632
- @check_index_exists ()
602
+ def aggregate (self , * args , ** kwargs ) -> "AggregateResult" :
603
+ """Perform an aggregation operation against the index.
604
+
605
+ Wrapper around the aggregation API that adds the index name
606
+ to the query and passes along the rest of the arguments
607
+ to the redis-py ft().aggregate() method.
608
+
609
+ Returns:
610
+ Result: Raw Redis aggregation results.
611
+ """
612
+ try :
613
+ return self ._redis_client .ft (self .schema .index .name ).aggregate ( # type: ignore
614
+ * args , ** kwargs
615
+ )
616
+ except Exception as e :
617
+ raise RedisSearchError (f"Error while aggregating: { str (e )} " ) from e
618
+
633
619
def search (self , * args , ** kwargs ) -> "Result" :
634
620
"""Perform a search against the index.
635
621
636
- Wrapper around redis. search.Search that adds the index name
637
- to the search query and passes along the rest of the arguments
638
- to the redis-py ft.search() method.
622
+ Wrapper around the search API that adds the index name
623
+ to the query and passes along the rest of the arguments
624
+ to the redis-py ft() .search() method.
639
625
640
626
Returns:
641
627
Result: Raw Redis search results.
@@ -644,9 +630,8 @@ def search(self, *args, **kwargs) -> "Result":
644
630
return self ._redis_client .ft (self .schema .index .name ).search ( # type: ignore
645
631
* args , ** kwargs
646
632
)
647
- except :
648
- logger .exception ("Error while searching" )
649
- raise
633
+ except Exception as e :
634
+ raise RedisSearchError (f"Error while searching: { str (e )} " ) from e
650
635
651
636
def _query (self , query : BaseQuery ) -> List [Dict [str , Any ]]:
652
637
"""Execute a query and process results."""
@@ -752,11 +737,11 @@ def _info(name: str, redis_client: redis.Redis) -> Dict[str, Any]:
752
737
"""Run FT.INFO to fetch information about the index."""
753
738
try :
754
739
return convert_bytes (redis_client .ft (name ).info ()) # type: ignore
755
- except :
756
- logger .exception (f"Error while fetching { name } index info" )
757
- raise
740
+ except Exception as e :
741
+ raise RedisSearchError (
742
+ f"Error while fetching { name } index info: { str (e )} "
743
+ ) from e
758
744
759
- @check_index_exists ()
760
745
def info (self , name : Optional [str ] = None ) -> Dict [str , Any ]:
761
746
"""Get information about the index.
762
747
@@ -1010,7 +995,6 @@ async def create(self, overwrite: bool = False, drop: bool = False) -> None:
1010
995
logger .exception ("Error while trying to create the index" )
1011
996
raise
1012
997
1013
- @check_async_index_exists ()
1014
998
async def delete (self , drop : bool = True ):
1015
999
"""Delete the search index.
1016
1000
@@ -1025,9 +1009,8 @@ async def delete(self, drop: bool = True):
1025
1009
await self ._redis_client .ft (self .schema .index .name ).dropindex ( # type: ignore
1026
1010
delete_documents = drop
1027
1011
)
1028
- except :
1029
- logger .exception ("Error while deleting index" )
1030
- raise
1012
+ except Exception as e :
1013
+ raise RedisSearchError (f"Error while deleting index: { str (e )} " ) from e
1031
1014
1032
1015
async def clear (self ) -> int :
1033
1016
"""Clear all keys in Redis associated with the index, leaving the index
@@ -1152,7 +1135,23 @@ async def fetch(self, id: str) -> Optional[Dict[str, Any]]:
1152
1135
return convert_bytes (obj [0 ])
1153
1136
return None
1154
1137
1155
- @check_async_index_exists ()
1138
+ async def aggregate (self , * args , ** kwargs ) -> "AggregateResult" :
1139
+ """Perform an aggregation operation against the index.
1140
+
1141
+ Wrapper around the aggregation API that adds the index name
1142
+ to the query and passes along the rest of the arguments
1143
+ to the redis-py ft().aggregate() method.
1144
+
1145
+ Returns:
1146
+ Result: Raw Redis aggregation results.
1147
+ """
1148
+ try :
1149
+ return await self ._redis_client .ft (self .schema .index .name ).aggregate ( # type: ignore
1150
+ * args , ** kwargs
1151
+ )
1152
+ except Exception as e :
1153
+ raise RedisSearchError (f"Error while aggregating: { str (e )} " ) from e
1154
+
1156
1155
async def search (self , * args , ** kwargs ) -> "Result" :
1157
1156
"""Perform a search on this index.
1158
1157
@@ -1167,9 +1166,8 @@ async def search(self, *args, **kwargs) -> "Result":
1167
1166
return await self ._redis_client .ft (self .schema .index .name ).search ( # type: ignore
1168
1167
* args , ** kwargs
1169
1168
)
1170
- except :
1171
- logger .exception ("Error while searching" )
1172
- raise
1169
+ except Exception as e :
1170
+ raise RedisSearchError (f"Error while searching: { str (e )} " ) from e
1173
1171
1174
1172
async def _query (self , query : BaseQuery ) -> List [Dict [str , Any ]]:
1175
1173
"""Asynchronously execute a query and process results."""
@@ -1275,11 +1273,11 @@ async def exists(self) -> bool:
1275
1273
async def _info (name : str , redis_client : aredis .Redis ) -> Dict [str , Any ]:
1276
1274
try :
1277
1275
return convert_bytes (await redis_client .ft (name ).info ()) # type: ignore
1278
- except :
1279
- logger .exception (f"Error while fetching { name } index info" )
1280
- raise
1276
+ except Exception as e :
1277
+ raise RedisSearchError (
1278
+ f"Error while fetching { name } index info: { str (e )} "
1279
+ ) from e
1281
1280
1282
- @check_async_index_exists ()
1283
1281
async def info (self , name : Optional [str ] = None ) -> Dict [str , Any ]:
1284
1282
"""Get information about the index.
1285
1283
0 commit comments