22
33import logging
44from time import monotonic , sleep
5- from typing import Any , Callable , Dict , List , Optional , Union
5+ from typing import Any , Callable , Dict , List , Optional
66
77from pymongo .collection import Collection
8- from pymongo .operations import SearchIndexModel
98
109logger = logging .getLogger (__file__ )
1110
1211
12+ # Don't break imports for modules that expect these functions
13+ # to be in this module.
14+
15+
1316def _vector_search_index_definition (
1417 dimensions : int ,
1518 path : str ,
@@ -34,133 +37,6 @@ def _vector_search_index_definition(
3437 return definition
3538
3639
37- def create_vector_search_index (
38- collection : Collection ,
39- index_name : str ,
40- dimensions : int ,
41- path : str ,
42- similarity : str ,
43- filters : Optional [List [str ]] = None ,
44- * ,
45- wait_until_complete : Optional [float ] = None ,
46- ** kwargs : Any ,
47- ) -> None :
48- """Experimental Utility function to create a vector search index
49-
50- Args:
51- collection (Collection): MongoDB Collection
52- index_name (str): Name of Index
53- dimensions (int): Number of dimensions in embedding
54- path (str): field with vector embedding
55- similarity (str): The similarity score used for the index
56- filters (List[str]): Fields/paths to index to allow filtering in $vectorSearch
57- wait_until_complete (Optional[float]): If provided, number of seconds to wait
58- until search index is ready.
59- kwargs: Keyword arguments supplying any additional options to SearchIndexModel.
60- """
61- logger .info ("Creating Search Index %s on %s" , index_name , collection .name )
62-
63- if collection .name not in collection .database .list_collection_names ():
64- collection .database .create_collection (collection .name )
65-
66- result = collection .create_search_index (
67- SearchIndexModel (
68- definition = _vector_search_index_definition (
69- dimensions = dimensions ,
70- path = path ,
71- similarity = similarity ,
72- filters = filters ,
73- ** kwargs ,
74- ),
75- name = index_name ,
76- type = "vectorSearch" ,
77- )
78- )
79-
80- if wait_until_complete :
81- _wait_for_predicate (
82- predicate = lambda : _is_index_ready (collection , index_name ),
83- err = f"{ index_name = } did not complete in { wait_until_complete } !" ,
84- timeout = wait_until_complete ,
85- )
86- logger .info (result )
87-
88-
89- def drop_vector_search_index (
90- collection : Collection ,
91- index_name : str ,
92- * ,
93- wait_until_complete : Optional [float ] = None ,
94- ) -> None :
95- """Drop a created vector search index
96-
97- Args:
98- collection (Collection): MongoDB Collection with index to be dropped
99- index_name (str): Name of the MongoDB index
100- wait_until_complete (Optional[float]): If provided, number of seconds to wait
101- until search index is ready.
102- """
103- logger .info (
104- "Dropping Search Index %s from Collection: %s" , index_name , collection .name
105- )
106- collection .drop_search_index (index_name )
107- if wait_until_complete :
108- _wait_for_predicate (
109- predicate = lambda : len (list (collection .list_search_indexes ())) == 0 ,
110- err = f"Index { index_name } did not drop in { wait_until_complete } !" ,
111- timeout = wait_until_complete ,
112- )
113- logger .info ("Vector Search index %s.%s dropped" , collection .name , index_name )
114-
115-
116- def update_vector_search_index (
117- collection : Collection ,
118- index_name : str ,
119- dimensions : int ,
120- path : str ,
121- similarity : str ,
122- filters : Optional [List [str ]] = None ,
123- * ,
124- wait_until_complete : Optional [float ] = None ,
125- ** kwargs : Any ,
126- ) -> None :
127- """Update a search index.
128-
129- Replace the existing index definition with the provided definition.
130-
131- Args:
132- collection (Collection): MongoDB Collection
133- index_name (str): Name of Index
134- dimensions (int): Number of dimensions in embedding
135- path (str): field with vector embedding
136- similarity (str): The similarity score used for the index.
137- filters (List[str]): Fields/paths to index to allow filtering in $vectorSearch
138- wait_until_complete (Optional[float]): If provided, number of seconds to wait
139- until search index is ready.
140- kwargs: Keyword arguments supplying any additional options to SearchIndexModel.
141- """
142- logger .info (
143- "Updating Search Index %s from Collection: %s" , index_name , collection .name
144- )
145- collection .update_search_index (
146- name = index_name ,
147- definition = _vector_search_index_definition (
148- dimensions = dimensions ,
149- path = path ,
150- similarity = similarity ,
151- filters = filters ,
152- ** kwargs ,
153- ),
154- )
155- if wait_until_complete :
156- _wait_for_predicate (
157- predicate = lambda : _is_index_ready (collection , index_name ),
158- err = f"Index { index_name } update did not complete in { wait_until_complete } !" ,
159- timeout = wait_until_complete ,
160- )
161- logger .info ("Update succeeded" )
162-
163-
16440def _is_index_ready (collection : Collection , index_name : str ) -> bool :
16541 """Check for the index name in the list of available search indexes to see if the
16642 specified index is of status READY
@@ -197,48 +73,3 @@ def _wait_for_predicate(
19773 if monotonic () - start > timeout :
19874 raise TimeoutError (err )
19975 sleep (interval )
200-
201-
202- def create_fulltext_search_index (
203- collection : Collection ,
204- index_name : str ,
205- field : Union [str , List [str ]],
206- * ,
207- wait_until_complete : Optional [float ] = None ,
208- ** kwargs : Any ,
209- ) -> None :
210- """Experimental Utility function to create an Atlas Search index
211-
212- Args:
213- collection (Collection): MongoDB Collection
214- index_name (str): Name of Index
215- field (str): Field to index
216- wait_until_complete (Optional[float]): If provided, number of seconds to wait
217- until search index is ready
218- kwargs: Keyword arguments supplying any additional options to SearchIndexModel.
219- """
220- logger .info ("Creating Search Index %s on %s" , index_name , collection .name )
221-
222- if collection .name not in collection .database .list_collection_names ():
223- collection .database .create_collection (collection .name )
224-
225- if isinstance (field , str ):
226- fields_definition = {field : [{"type" : "string" }]}
227- else :
228- fields_definition = {f : [{"type" : "string" }] for f in field }
229- definition = {"mappings" : {"dynamic" : False , "fields" : fields_definition }}
230- result = collection .create_search_index (
231- SearchIndexModel (
232- definition = definition ,
233- name = index_name ,
234- type = "search" ,
235- ** kwargs ,
236- )
237- )
238- if wait_until_complete :
239- _wait_for_predicate (
240- predicate = lambda : _is_index_ready (collection , index_name ),
241- err = f"{ index_name = } did not complete in { wait_until_complete } !" ,
242- timeout = wait_until_complete ,
243- )
244- logger .info (result )
0 commit comments