@@ -20,14 +20,33 @@ pub fn handler() -> ApiRouter {
2020 ApiRouter :: new ( ) . nest (
2121 "/collections" ,
2222 ApiRouter :: new ( )
23+ . api_route ( "/" , get ( get_collections) )
2324 . api_route ( "/:collection_name" , put ( create_collection) )
2425 . api_route ( "/:collection_name" , post ( query_collection) )
2526 . api_route ( "/:collection_name" , get ( get_collection_info) )
2627 . api_route ( "/:collection_name" , delete ( delete_collection) )
27- . api_route ( "/:collection_name/insert" , post ( insert_into_collection) ) ,
28+ . api_route ( "/:collection_name/insert" , post ( insert_into_collection) )
29+ . api_route ( "/:collection_name/embeddings" , get ( get_embeddings) )
30+ . api_route ( "/:collection_name/embeddings" , post ( query_embeddings) )
31+ . api_route ( "/:collection_name/embeddings" , delete ( delete_embeddings) )
32+ . api_route ( "/:collection_name/embeddings/:embedding_id" , get ( get_embedding) )
33+ . api_route ( "/:collection_name/embeddings/:embedding_id" , delete ( delete_embedding) ) ,
2834 )
2935}
3036
37+ /// Get collection names
38+ async fn get_collections (
39+ Extension ( db) : DbExtension ,
40+ ) -> Result < Json < Vec < String > > , HTTPError > {
41+ tracing:: trace!( "Getting collection names" ) ;
42+
43+ let db = db. read ( ) . await ;
44+
45+ let results = db. list ( ) ;
46+
47+ Ok ( Json ( results) )
48+ }
49+
3150/// Create a new collection
3251async fn create_collection (
3352 Path ( collection_name) : Path < String > ,
@@ -170,3 +189,113 @@ async fn insert_into_collection(
170189 . with_status ( StatusCode :: BAD_REQUEST ) ) ,
171190 }
172191}
192+
193+ /// Query embeddings in a collection
194+ async fn get_embeddings (
195+ Path ( collection_name) : Path < String > ,
196+ Extension ( db) : DbExtension ,
197+ ) -> Result < Json < Vec < String > > , HTTPError > {
198+ tracing:: trace!( "Querying embeddings from collection {collection_name}" ) ;
199+
200+ let db = db. read ( ) . await ;
201+ let collection = db
202+ . get_collection ( & collection_name)
203+ . ok_or_else ( || HTTPError :: new ( "Collection not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
204+
205+ let results = collection. list ( ) ;
206+ drop ( db) ;
207+
208+ Ok ( Json ( results) )
209+ }
210+
211+ #[ derive( Debug , serde:: Deserialize , JsonSchema ) ]
212+ struct EmbeddingsQuery {
213+ /// Metadata to filter with
214+ filter : Vec < HashMap < String , String > > ,
215+ /// Number of results to return
216+ k : Option < usize > ,
217+ }
218+
219+ /// Query embeddings in a collection
220+ async fn query_embeddings (
221+ Path ( collection_name) : Path < String > ,
222+ Extension ( db) : DbExtension ,
223+ Json ( req) : Json < EmbeddingsQuery > ,
224+ ) -> Result < Json < Vec < Embedding > > , HTTPError > {
225+ tracing:: trace!( "Querying embeddings from collection {collection_name}" ) ;
226+
227+ let db = db. read ( ) . await ;
228+ let collection = db
229+ . get_collection ( & collection_name)
230+ . ok_or_else ( || HTTPError :: new ( "Collection not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
231+
232+ let instant = Instant :: now ( ) ;
233+ let results = collection. get_by_metadata ( & req. filter , req. k . unwrap_or ( 1 ) ) ;
234+ drop ( db) ;
235+
236+ tracing:: trace!( "Query embeddings from {collection_name} took {:?}" , instant. elapsed( ) ) ;
237+ Ok ( Json ( results) )
238+ }
239+
240+ /// Delete embeddings in a collection
241+ async fn delete_embeddings (
242+ Path ( collection_name) : Path < String > ,
243+ Extension ( db) : DbExtension ,
244+ Json ( req) : Json < EmbeddingsQuery > ,
245+ ) -> Result < StatusCode , HTTPError > {
246+ tracing:: trace!( "Querying embeddings from collection {collection_name}" ) ;
247+
248+ let mut db = db. write ( ) . await ;
249+ let collection = db
250+ . get_collection_mut ( & collection_name)
251+ . ok_or_else ( || HTTPError :: new ( "Collection not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
252+
253+ collection. delete_by_metadata ( & req. filter ) ;
254+ drop ( db) ;
255+
256+ Ok ( StatusCode :: NO_CONTENT )
257+ }
258+
259+ /// Get an embedding from a collection
260+ async fn get_embedding (
261+ Path ( ( collection_name, embedding_id) ) : Path < ( String , String ) > ,
262+ Extension ( db) : DbExtension ,
263+ ) -> Result < Json < Embedding > , HTTPError > {
264+ tracing:: trace!( "Getting {embedding_id} from collection {collection_name}" ) ;
265+
266+ if embedding_id. len ( ) == 0 {
267+ return Err ( HTTPError :: new ( "Embedding identifier empty" ) . with_status ( StatusCode :: BAD_REQUEST ) ) ;
268+ }
269+
270+ let db = db. read ( ) . await ;
271+ let collection = db
272+ . get_collection ( & collection_name)
273+ . ok_or_else ( || HTTPError :: new ( "Collection not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
274+
275+ let embedding = collection
276+ . get ( & embedding_id)
277+ . ok_or_else ( || HTTPError :: new ( "Embedding not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
278+
279+ Ok ( Json ( embedding. to_owned ( ) ) )
280+ }
281+
282+ /// Delete an embedding from a collection
283+ async fn delete_embedding (
284+ Path ( ( collection_name, embedding_id) ) : Path < ( String , String ) > ,
285+ Extension ( db) : DbExtension ,
286+ ) -> Result < StatusCode , HTTPError > {
287+ tracing:: trace!( "Removing embedding {embedding_id} from collection {collection_name}" ) ;
288+
289+ let mut db = db. write ( ) . await ;
290+ let collection = db
291+ . get_collection_mut ( & collection_name)
292+ . ok_or_else ( || HTTPError :: new ( "Collection not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ?;
293+
294+ let delete_result = collection. delete ( & embedding_id) ;
295+ drop ( db) ;
296+
297+ match delete_result {
298+ true => Ok ( StatusCode :: NO_CONTENT ) ,
299+ false => Err ( HTTPError :: new ( "Embedding not found" ) . with_status ( StatusCode :: NOT_FOUND ) ) ,
300+ }
301+ }
0 commit comments