2024-09-19 10:55:20 +02:00
mod binary_quantized ;
2024-07-30 15:43:40 +02:00
mod openai ;
2024-06-12 18:27:03 +02:00
mod rest ;
2024-06-11 16:03:45 +02:00
mod settings ;
2024-07-30 15:41:51 +02:00
use std ::str ::FromStr ;
2024-06-06 10:41:16 +02:00
use meili_snap ::{ json_string , snapshot } ;
2024-07-30 15:41:51 +02:00
use meilisearch ::option ::MaxThreads ;
2024-06-06 10:41:16 +02:00
2024-06-11 16:03:45 +02:00
use crate ::common ::index ::Index ;
2024-07-30 15:41:51 +02:00
use crate ::common ::{ default_settings , GetAllDocumentsOptions , Server } ;
2024-06-06 10:41:16 +02:00
use crate ::json ;
2024-07-30 15:43:40 +02:00
async fn get_server_vector ( ) -> Server {
let server = Server ::new ( ) . await ;
let ( value , code ) = server . set_features ( json! ( { " vectorStore " : true } ) ) . await ;
snapshot! ( code , @ " 200 OK " ) ;
snapshot! ( value , @ r ###"
{
" vectorStore " : true ,
" metrics " : false ,
" logsRoute " : false ,
" editDocumentsByFunction " : false ,
" containsFilter " : false
}
" ###);
server
}
2024-06-06 10:41:16 +02:00
#[ actix_rt::test ]
async fn add_remove_user_provided ( ) {
let server = Server ::new ( ) . await ;
let index = server . index ( " doggo " ) ;
let ( value , code ) = server . set_features ( json! ( { " vectorStore " : true } ) ) . await ;
snapshot! ( code , @ " 200 OK " ) ;
snapshot! ( value , @ r ###"
{
" vectorStore " : true ,
" metrics " : false ,
2024-07-09 11:15:57 +02:00
" logsRoute " : false ,
2024-07-17 11:13:37 +02:00
" editDocumentsByFunction " : false ,
" containsFilter " : false
2024-06-06 10:41:16 +02:00
}
" ###);
let ( response , code ) = index
. update_settings ( json! ( {
" embedders " : {
" manual " : {
" source " : " userProvided " ,
" dimensions " : 3 ,
}
} ,
} ) )
. await ;
snapshot! ( code , @ " 202 Accepted " ) ;
server . wait_task ( response . uid ( ) ) . await ;
let documents = json! ( [
{ " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : [ 0 , 0 , 0 ] } } ,
{ " id " : 1 , " name " : " echo " , " _vectors " : { " manual " : [ 1 , 1 , 1 ] } } ,
] ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
index . wait_task ( value . uid ( ) ) . await ;
let ( documents , _code ) = index
. get_all_documents ( GetAllDocumentsOptions { retrieve_vectors : true , .. Default ::default ( ) } )
. await ;
snapshot! ( json_string! ( documents ) , @ r ###"
{
" results " : [
{
" id " : 0 ,
" name " : " kefir " ,
" _vectors " : {
" manual " : {
" embeddings " : [
[
0.0 ,
0.0 ,
0.0
]
] ,
2024-06-12 18:13:34 +02:00
" regenerate " : false
2024-06-06 10:41:16 +02:00
}
}
} ,
{
" id " : 1 ,
" name " : " echo " ,
" _vectors " : {
" manual " : {
" embeddings " : [
[
1.0 ,
1.0 ,
1.0
]
] ,
2024-06-12 18:13:34 +02:00
" regenerate " : false
2024-06-06 10:41:16 +02:00
}
}
}
] ,
" offset " : 0 ,
" limit " : 20 ,
" total " : 2
}
" ###);
let documents = json! ( [
{ " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : [ 10 , 10 , 10 ] } } ,
{ " id " : 1 , " name " : " echo " , " _vectors " : { " manual " : null } } ,
] ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
index . wait_task ( value . uid ( ) ) . await ;
let ( documents , _code ) = index
. get_all_documents ( GetAllDocumentsOptions { retrieve_vectors : true , .. Default ::default ( ) } )
. await ;
snapshot! ( json_string! ( documents ) , @ r ###"
{
" results " : [
{
" id " : 0 ,
" name " : " kefir " ,
" _vectors " : {
" manual " : {
" embeddings " : [
[
10.0 ,
10.0 ,
10.0
]
] ,
2024-06-12 18:13:34 +02:00
" regenerate " : false
2024-06-06 10:41:16 +02:00
}
}
} ,
{
" id " : 1 ,
" name " : " echo " ,
2024-07-16 10:44:23 +02:00
" _vectors " : {
" manual " : {
" embeddings " : [ ] ,
" regenerate " : false
}
}
2024-06-06 10:41:16 +02:00
}
] ,
" offset " : 0 ,
" limit " : 20 ,
" total " : 2
}
" ###);
let ( value , code ) = index . delete_document ( 0 ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
index . wait_task ( value . uid ( ) ) . await ;
let ( documents , _code ) = index
. get_all_documents ( GetAllDocumentsOptions { retrieve_vectors : true , .. Default ::default ( ) } )
. await ;
snapshot! ( json_string! ( documents ) , @ r ###"
{
" results " : [
{
" id " : 1 ,
" name " : " echo " ,
2024-07-16 10:44:23 +02:00
" _vectors " : {
" manual " : {
" embeddings " : [ ] ,
" regenerate " : false
}
}
2024-06-06 10:41:16 +02:00
}
] ,
" offset " : 0 ,
" limit " : 20 ,
" total " : 1
}
" ###);
}
2024-06-11 16:03:45 +02:00
async fn generate_default_user_provided_documents ( server : & Server ) -> Index {
let index = server . index ( " doggo " ) ;
let ( value , code ) = server . set_features ( json! ( { " vectorStore " : true } ) ) . await ;
snapshot! ( code , @ " 200 OK " ) ;
snapshot! ( value , @ r ###"
{
" vectorStore " : true ,
" metrics " : false ,
2024-07-09 11:15:57 +02:00
" logsRoute " : false ,
2024-07-17 11:13:37 +02:00
" editDocumentsByFunction " : false ,
" containsFilter " : false
2024-06-11 16:03:45 +02:00
}
" ###);
let ( response , code ) = index
. update_settings ( json! ( {
" embedders " : {
" manual " : {
" source " : " userProvided " ,
" dimensions " : 3 ,
}
} ,
} ) )
. await ;
snapshot! ( code , @ " 202 Accepted " ) ;
server . wait_task ( response . uid ( ) ) . await ;
let documents = json! ( [
{ " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : [ 0 , 0 , 0 ] } } ,
{ " id " : 1 , " name " : " echo " , " _vectors " : { " manual " : [ 1 , 1 , 1 ] } } ,
{ " id " : 2 , " name " : " billou " , " _vectors " : { " manual " : [ [ 2 , 2 , 2 ] , [ 2 , 2 , 3 ] ] } } ,
2024-06-12 18:13:34 +02:00
{ " id " : 3 , " name " : " intel " , " _vectors " : { " manual " : { " regenerate " : false , " embeddings " : [ 3 , 3 , 3 ] } } } ,
{ " id " : 4 , " name " : " max " , " _vectors " : { " manual " : { " regenerate " : false , " embeddings " : [ [ 4 , 4 , 4 ] , [ 4 , 4 , 5 ] ] } } } ,
2024-06-11 16:03:45 +02:00
] ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
index . wait_task ( value . uid ( ) ) . await ;
index
}
2024-06-27 11:01:52 +02:00
#[ actix_rt::test ]
async fn user_provided_embeddings_error ( ) {
let server = Server ::new ( ) . await ;
let index = generate_default_user_provided_documents ( & server ) . await ;
// First case, we forget to specify the `regenerate`
let documents =
json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " embeddings " : [ 0 , 0 , 0 ] } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Missing field `._vectors.manual.regenerate` \n - note: `._vectors.manual` must be an array of floats, an array of arrays of floats, or an object with field `regenerate` " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
// Second case, we don't specify anything
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Missing field `._vectors.manual.regenerate` \n - note: `._vectors.manual` must be an array of floats, an array of arrays of floats, or an object with field `regenerate` " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
// Third case, we specify something wrong in place of regenerate
let documents =
json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " regenerate " : " yes please " } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Could not parse `._vectors.manual.regenerate`: invalid type: string \" yes please \" , expected a boolean at line 1 column 26 " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
2024-11-12 22:49:40 +01:00
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " embeddings " : true , " regenerate " : true } } } ) ;
2024-06-27 11:01:52 +02:00
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings`: expected null or an array, but found a boolean: `true` " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
2024-11-12 22:49:40 +01:00
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " embeddings " : [ true ] , " regenerate " : true } } } ) ;
2024-06-27 11:01:52 +02:00
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings[0]`: expected a number or an array, but found a boolean: `true` " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
2024-11-12 22:49:40 +01:00
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " embeddings " : [ [ true ] ] , " regenerate " : false } } } ) ;
2024-06-27 11:01:52 +02:00
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings[0][0]`: expected a number, but found a boolean: `true` " ,
2024-06-27 11:01:52 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " embeddings " : [ 23 , 0.1 , - 12 ] , " regenerate " : true } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
2024-06-27 11:51:45 +02:00
snapshot! ( task [ " status " ] , @ r ### ""succeeded""### ) ;
let documents =
json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " regenerate " : false } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task [ " status " ] , @ r ### ""succeeded""### ) ;
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " regenerate " : false , " embeddings " : [ 0.1 , [ 0.2 , 0.3 ] ] } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:51:45 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings[1]`: expected a number, but found an array: `[0.2,0.3]` " ,
2024-06-27 11:51:45 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " regenerate " : false , " embeddings " : [ [ 0.1 , 0.2 ] , 0.3 ] } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
2024-06-27 11:01:52 +02:00
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:01:52 +02:00
" indexUid " : " doggo " ,
2024-06-27 11:51:45 +02:00
" status " : " failed " ,
2024-06-27 11:01:52 +02:00
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
2024-06-27 11:51:45 +02:00
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings[1]`: expected an array, but found a number: `0.3` " ,
2024-06-27 11:51:45 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
let documents = json! ( { " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : { " regenerate " : false , " embeddings " : [ [ 0.1 , true ] , 0.3 ] } } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-06-27 11:51:45 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-11-12 22:49:40 +01:00
" message " : " Bad embedder configuration in the document with id: `0`. Invalid value type at `._vectors.manual.embeddings[0][1]`: expected a number, but found a boolean: `true` " ,
2024-06-27 11:51:45 +02:00
" code " : " invalid_vectors_type " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#invalid_vectors_type "
2024-06-27 11:01:52 +02:00
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
}
2024-07-16 11:09:17 +02:00
#[ actix_rt::test ]
async fn user_provided_vectors_error ( ) {
2024-07-30 15:41:51 +02:00
let temp = tempfile ::tempdir ( ) . unwrap ( ) ;
let mut options = default_settings ( temp . path ( ) ) ;
// If we have more than one indexing thread the error messages below may become inconsistent
options . indexer_options . max_indexing_threads = MaxThreads ::from_str ( " 1 " ) . unwrap ( ) ;
let server = Server ::new_with_options ( options ) . await . unwrap ( ) ;
2024-07-22 15:42:04 +02:00
2024-07-16 11:09:17 +02:00
let index = generate_default_user_provided_documents ( & server ) . await ;
// First case, we forget to specify `_vectors`
2024-07-22 15:42:04 +02:00
let documents = json! ( [ { " id " : 40 , " name " : " kefir " } , { " id " : 41 , " name " : " intel " } , { " id " : 42 , " name " : " max " } , { " id " : 43 , " name " : " venus " } , { " id " : 44 , " name " : " eva " } ] ) ;
2024-07-16 11:09:17 +02:00
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-07-16 11:09:17 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
2024-07-22 15:42:04 +02:00
" receivedDocuments " : 5 ,
2024-07-16 11:09:17 +02:00
" indexedDocuments " : 0
} ,
" error " : {
2024-07-22 15:42:04 +02:00
" message " : " While embedding documents for embedder `manual`: no vectors provided for document \" 40 \" and at least 4 other document(s) \n - Note: `manual` has `source: userProvided`, so documents must provide embeddings as an array in `_vectors.manual`. \n - Hint: opt-out for a document with `_vectors.manual: null` " ,
2024-07-16 11:09:17 +02:00
" code " : " vector_embedding_error " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#vector_embedding_error "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
// Second case, we provide `_vectors` with a typo
let documents = json! ( { " id " : 42 , " name " : " kefir " , " _vector " : { " manaul " : [ 0 , 0 , 0 ] } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-07-16 11:09:17 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-07-22 15:42:04 +02:00
" message " : " While embedding documents for embedder `manual`: no vectors provided for document \" 42 \" \n - Note: `manual` has `source: userProvided`, so documents must provide embeddings as an array in `_vectors.manual`. \n - Hint: try replacing `_vector` by `_vectors` in 1 document(s). " ,
2024-07-16 11:09:17 +02:00
" code " : " vector_embedding_error " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#vector_embedding_error "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
// Third case, we specify the embedder with a typo
let documents = json! ( { " id " : 42 , " name " : " kefir " , " _vectors " : { " manaul " : [ 0 , 0 , 0 ] } } ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , @ r ###"
{
2024-07-18 16:32:50 +02:00
" uid " : " [uid] " ,
2024-07-16 11:09:17 +02:00
" indexUid " : " doggo " ,
" status " : " failed " ,
" type " : " documentAdditionOrUpdate " ,
" canceledBy " : null ,
" details " : {
" receivedDocuments " : 1 ,
" indexedDocuments " : 0
} ,
" error " : {
2024-07-22 15:42:04 +02:00
" message " : " While embedding documents for embedder `manual`: no vectors provided for document \" 42 \" \n - Note: `manual` has `source: userProvided`, so documents must provide embeddings as an array in `_vectors.manual`. \n - Hint: try replacing `_vectors.manaul` by `_vectors.manual` in 1 document(s). " ,
2024-07-16 11:09:17 +02:00
" code " : " vector_embedding_error " ,
" type " : " invalid_request " ,
" link " : " https://docs.meilisearch.com/errors#vector_embedding_error "
} ,
" duration " : " [duration] " ,
" enqueuedAt " : " [date] " ,
" startedAt " : " [date] " ,
" finishedAt " : " [date] "
}
" ###);
}
2024-06-11 16:03:45 +02:00
#[ actix_rt::test ]
async fn clear_documents ( ) {
let server = Server ::new ( ) . await ;
let index = generate_default_user_provided_documents ( & server ) . await ;
let ( value , _code ) = index . clear_all_documents ( ) . await ;
index . wait_task ( value . uid ( ) ) . await ;
// Make sure the documents DB has been cleared
let ( documents , _code ) = index
. get_all_documents ( GetAllDocumentsOptions { retrieve_vectors : true , .. Default ::default ( ) } )
. await ;
snapshot! ( json_string! ( documents ) , @ r ###"
{
" results " : [ ] ,
" offset " : 0 ,
" limit " : 20 ,
" total " : 0
}
" ###);
// Make sure the arroy DB has been cleared
2024-09-17 16:30:04 +02:00
let ( documents , _code ) =
index . search_post ( json! ( { " vector " : [ 1 , 1 , 1 ] , " hybrid " : { " embedder " : " manual " } } ) ) . await ;
2024-06-24 11:13:45 +02:00
snapshot! ( documents , @ r ###"
2024-06-11 16:03:45 +02:00
{
" hits " : [ ] ,
" query " : " " ,
2024-06-24 11:13:45 +02:00
" processingTimeMs " : " [duration] " ,
2024-06-11 16:03:45 +02:00
" limit " : 20 ,
" offset " : 0 ,
" estimatedTotalHits " : 0 ,
" semanticHitCount " : 0
}
" ###);
}
2024-06-20 15:59:32 +02:00
#[ actix_rt::test ]
async fn add_remove_one_vector_4588 ( ) {
// https://github.com/meilisearch/meilisearch/issues/4588
let server = Server ::new ( ) . await ;
let index = server . index ( " doggo " ) ;
let ( value , code ) = server . set_features ( json! ( { " vectorStore " : true } ) ) . await ;
snapshot! ( code , @ " 200 OK " ) ;
snapshot! ( value , @ r ###"
{
" vectorStore " : true ,
" metrics " : false ,
2024-07-09 11:15:57 +02:00
" logsRoute " : false ,
2024-07-17 11:13:37 +02:00
" editDocumentsByFunction " : false ,
" containsFilter " : false
2024-06-20 15:59:32 +02:00
}
" ###);
let ( response , code ) = index
. update_settings ( json! ( {
" embedders " : {
" manual " : {
" source " : " userProvided " ,
" dimensions " : 3 ,
}
} ,
} ) )
. await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = server . wait_task ( response . uid ( ) ) . await ;
snapshot! ( task , name : " settings-processed " ) ;
let documents = json! ( [
{ " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : [ 0 , 0 , 0 ] } } ,
] ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , name : " document-added " ) ;
let documents = json! ( [
{ " id " : 0 , " name " : " kefir " , " _vectors " : { " manual " : null } } ,
] ) ;
let ( value , code ) = index . add_documents ( documents , None ) . await ;
snapshot! ( code , @ " 202 Accepted " ) ;
let task = index . wait_task ( value . uid ( ) ) . await ;
snapshot! ( task , name : " document-deleted " ) ;
2024-09-17 16:30:04 +02:00
let ( documents , _code ) = index
. search_post (
json! ( { " vector " : [ 1 , 1 , 1 ] , " hybrid " : { " semanticRatio " : 1.0 , " embedder " : " manual " } } ) ,
)
. await ;
2024-06-24 11:13:45 +02:00
snapshot! ( documents , @ r ###"
2024-06-20 15:59:32 +02:00
{
" hits " : [
{
" id " : 0 ,
" name " : " kefir "
}
] ,
" query " : " " ,
2024-06-24 11:13:45 +02:00
" processingTimeMs " : " [duration] " ,
2024-06-20 15:59:32 +02:00
" limit " : 20 ,
" offset " : 0 ,
" estimatedTotalHits " : 1 ,
" semanticHitCount " : 1
}
" ###);
let ( documents , _code ) = index
. get_all_documents ( GetAllDocumentsOptions { retrieve_vectors : true , .. Default ::default ( ) } )
. await ;
snapshot! ( json_string! ( documents ) , @ r ###"
{
" results " : [
{
" id " : 0 ,
" name " : " kefir " ,
2024-07-16 10:44:23 +02:00
" _vectors " : {
" manual " : {
" embeddings " : [ ] ,
" regenerate " : false
}
}
2024-06-20 15:59:32 +02:00
}
] ,
" offset " : 0 ,
" limit " : 20 ,
" total " : 1
}
" ###);
}