From 600e97d9dcec39588bd4c305a607fc0025620e15 Mon Sep 17 00:00:00 2001 From: Tamo Date: Mon, 10 Jun 2024 18:26:12 +0200 Subject: [PATCH] gate the retrieveVectors parameter behind the vectors feature flag --- meilisearch/src/routes/indexes/documents.rs | 24 +++++++++--- meilisearch/src/routes/indexes/search.rs | 8 ++-- meilisearch/tests/documents/errors.rs | 43 +++++++++++++++++++++ meilisearch/tests/search/mod.rs | 41 ++++++++++++++------ 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/meilisearch/src/routes/indexes/documents.rs b/meilisearch/src/routes/indexes/documents.rs index 81e297d54..70623bb35 100644 --- a/meilisearch/src/routes/indexes/documents.rs +++ b/meilisearch/src/routes/indexes/documents.rs @@ -110,14 +110,18 @@ pub async fn get_document( debug!(parameters = ?params, "Get document"); let index_uid = IndexUid::try_from(index_uid)?; - analytics.get_fetch_documents( - &DocumentFetchKind::PerDocumentId { retrieve_vectors: params.retrieve_vectors.0 }, - &req, - ); - let GetDocument { fields, retrieve_vectors } = params.into_inner(); let attributes_to_retrieve = fields.merge_star_and_none(); + let features = index_scheduler.features(); + if retrieve_vectors.0 { + features.check_vector("Passing `retrieveVectors` as a parameter")?; + } + analytics.get_fetch_documents( + &DocumentFetchKind::PerDocumentId { retrieve_vectors: retrieve_vectors.0 }, + &req, + ); + let index = index_scheduler.index(&index_uid)?; let document = retrieve_document(&index, &document_id, attributes_to_retrieve, retrieve_vectors.0)?; @@ -191,6 +195,11 @@ pub async fn documents_by_query_post( let body = body.into_inner(); debug!(parameters = ?body, "Get documents POST"); + let features = index_scheduler.features(); + if body.retrieve_vectors { + features.check_vector("Passing `retrieveVectors` as a parameter")?; + } + analytics.post_fetch_documents( &DocumentFetchKind::Normal { with_filter: body.filter.is_some(), @@ -215,6 +224,11 @@ pub async fn get_documents( let BrowseQueryGet { limit, offset, fields, retrieve_vectors, filter } = params.into_inner(); + let features = index_scheduler.features(); + if retrieve_vectors.0 { + features.check_vector("Passing `retrieveVectors` as a parameter")?; + } + let filter = match filter { Some(f) => match serde_json::from_str(&f) { Ok(v) => Some(v), diff --git a/meilisearch/src/routes/indexes/search.rs b/meilisearch/src/routes/indexes/search.rs index ae6402cf6..6fdff4568 100644 --- a/meilisearch/src/routes/indexes/search.rs +++ b/meilisearch/src/routes/indexes/search.rs @@ -290,11 +290,13 @@ pub fn search_kind( features: RoFeatures, ) -> Result { if query.vector.is_some() { - features.check_vector("Passing `vector` as a query parameter")?; + features.check_vector("Passing `vector` as a parameter")?; } - if query.hybrid.is_some() { - features.check_vector("Passing `hybrid` as a query parameter")?; + features.check_vector("Passing `hybrid` as a parameter")?; + } + if query.retrieve_vectors { + features.check_vector("Passing `retrieveVectors` as a parameter")?; } // regardless of anything, always do a keyword search when we don't have a vector and the query is whitespace or missing diff --git a/meilisearch/tests/documents/errors.rs b/meilisearch/tests/documents/errors.rs index cd1be4dc4..8e9a3a696 100644 --- a/meilisearch/tests/documents/errors.rs +++ b/meilisearch/tests/documents/errors.rs @@ -800,6 +800,8 @@ async fn fetch_document_by_filter() { async fn retrieve_vectors() { let server = Server::new().await; let index = server.index("doggo"); + + // GET ALL DOCUMENTS BY QUERY let (response, _code) = index.get_all_documents_raw("?retrieveVectors=tamo").await; snapshot!(json_string!(response), @r###" { @@ -809,6 +811,38 @@ async fn retrieve_vectors() { "link": "https://docs.meilisearch.com/errors#invalid_document_retrieve_vectors" } "###); + let (response, _code) = index.get_all_documents_raw("?retrieveVectors=true").await; + snapshot!(json_string!(response), @r###" + { + "message": "Passing `retrieveVectors` as a parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", + "code": "feature_not_enabled", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#feature_not_enabled" + } + "###); + + // FETCH ALL DOCUMENTS BY POST + let (response, _code) = + index.get_document_by_filter(json!({ "retrieveVectors": "tamo" })).await; + snapshot!(json_string!(response), @r###" + { + "message": "Invalid value type at `.retrieveVectors`: expected a boolean, but found a string: `\"tamo\"`", + "code": "invalid_document_retrieve_vectors", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#invalid_document_retrieve_vectors" + } + "###); + let (response, _code) = index.get_document_by_filter(json!({ "retrieveVectors": true })).await; + snapshot!(json_string!(response), @r###" + { + "message": "Passing `retrieveVectors` as a parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", + "code": "feature_not_enabled", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#feature_not_enabled" + } + "###); + + // GET A SINGLE DOCUMENT let (response, _code) = index.get_document(0, Some(json!({"retrieveVectors": "tamo"}))).await; snapshot!(json_string!(response), @r###" { @@ -818,4 +852,13 @@ async fn retrieve_vectors() { "link": "https://docs.meilisearch.com/errors#invalid_document_retrieve_vectors" } "###); + let (response, _code) = index.get_document(0, Some(json!({"retrieveVectors": true}))).await; + snapshot!(json_string!(response), @r###" + { + "message": "Passing `retrieveVectors` as a parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", + "code": "feature_not_enabled", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#feature_not_enabled" + } + "###); } diff --git a/meilisearch/tests/search/mod.rs b/meilisearch/tests/search/mod.rs index 9e19fa4e8..19e495edd 100644 --- a/meilisearch/tests/search/mod.rs +++ b/meilisearch/tests/search/mod.rs @@ -1290,21 +1290,38 @@ async fn experimental_feature_vector_store() { index.add_documents(json!(documents), None).await; index.wait_task(0).await; - let (response, code) = index - .search_post(json!({ + index + .search(json!({ "vector": [1.0, 2.0, 3.0], "showRankingScore": true - })) + }), |response, code|{ + meili_snap::snapshot!(code, @"400 Bad Request"); + meili_snap::snapshot!(meili_snap::json_string!(response), @r###" + { + "message": "Passing `vector` as a parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", + "code": "feature_not_enabled", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#feature_not_enabled" + } + "###); + }) + .await; + index + .search(json!({ + "retrieveVectors": true, + "showRankingScore": true + }), |response, code|{ + meili_snap::snapshot!(code, @"400 Bad Request"); + meili_snap::snapshot!(meili_snap::json_string!(response), @r###" + { + "message": "Passing `retrieveVectors` as a parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", + "code": "feature_not_enabled", + "type": "invalid_request", + "link": "https://docs.meilisearch.com/errors#feature_not_enabled" + } + "###); + }) .await; - meili_snap::snapshot!(code, @"400 Bad Request"); - meili_snap::snapshot!(meili_snap::json_string!(response), @r###" - { - "message": "Passing `vector` as a query parameter requires enabling the `vector store` experimental feature. See https://github.com/meilisearch/product/discussions/677", - "code": "feature_not_enabled", - "type": "invalid_request", - "link": "https://docs.meilisearch.com/errors#feature_not_enabled" - } - "###); let (response, code) = server.set_features(json!({"vectorStore": true})).await; meili_snap::snapshot!(code, @"200 OK");