mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-04 12:27:13 +02:00
WIP
- manual embedder - multi embedders OK - clippy + tests OK
This commit is contained in:
parent
922a640188
commit
12940d79a9
13 changed files with 292 additions and 140 deletions
|
@ -235,38 +235,42 @@ pub async fn embed(
|
|||
index_scheduler: &IndexScheduler,
|
||||
index: &milli::Index,
|
||||
) -> Result<(), ResponseError> {
|
||||
if let Some(VectorQuery::String(prompt)) = query.vector.take() {
|
||||
let embedder_configs = index.embedding_configs(&index.read_txn()?)?;
|
||||
let embedder = index_scheduler.embedders(embedder_configs)?;
|
||||
match query.vector.take() {
|
||||
Some(VectorQuery::String(prompt)) => {
|
||||
let embedder_configs = index.embedding_configs(&index.read_txn()?)?;
|
||||
let embedder = index_scheduler.embedders(embedder_configs)?;
|
||||
|
||||
let embedder_name = if let Some(HybridQuery {
|
||||
semantic_ratio: _,
|
||||
embedder: Some(embedder),
|
||||
}) = &query.hybrid
|
||||
{
|
||||
embedder
|
||||
} else {
|
||||
"default"
|
||||
};
|
||||
let embedder_name =
|
||||
if let Some(HybridQuery { semantic_ratio: _, embedder: Some(embedder) }) =
|
||||
&query.hybrid
|
||||
{
|
||||
embedder
|
||||
} else {
|
||||
"default"
|
||||
};
|
||||
|
||||
let embeddings = embedder
|
||||
.get(embedder_name)
|
||||
.ok_or(milli::UserError::InvalidEmbedder(embedder_name.to_owned()))
|
||||
.map_err(milli::Error::from)?
|
||||
.0
|
||||
.embed(vec![prompt])
|
||||
.await
|
||||
.map_err(milli::vector::Error::from)
|
||||
.map_err(milli::Error::from)?
|
||||
.pop()
|
||||
.expect("No vector returned from embedding");
|
||||
let embeddings = embedder
|
||||
.get(embedder_name)
|
||||
.ok_or(milli::UserError::InvalidEmbedder(embedder_name.to_owned()))
|
||||
.map_err(milli::Error::from)?
|
||||
.0
|
||||
.embed(vec![prompt])
|
||||
.await
|
||||
.map_err(milli::vector::Error::from)
|
||||
.map_err(milli::Error::from)?
|
||||
.pop()
|
||||
.expect("No vector returned from embedding");
|
||||
|
||||
if embeddings.iter().nth(1).is_some() {
|
||||
warn!("Ignoring embeddings past the first one in long search query");
|
||||
query.vector = Some(VectorQuery::Vector(embeddings.iter().next().unwrap().to_vec()));
|
||||
} else {
|
||||
query.vector = Some(VectorQuery::Vector(embeddings.into_inner()));
|
||||
if embeddings.iter().nth(1).is_some() {
|
||||
warn!("Ignoring embeddings past the first one in long search query");
|
||||
query.vector =
|
||||
Some(VectorQuery::Vector(embeddings.iter().next().unwrap().to_vec()));
|
||||
} else {
|
||||
query.vector = Some(VectorQuery::Vector(embeddings.into_inner()));
|
||||
}
|
||||
}
|
||||
Some(vector) => query.vector = Some(vector),
|
||||
None => {}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use meilisearch_types::deserr::DeserrJsonError;
|
|||
use meilisearch_types::error::deserr_codes::*;
|
||||
use meilisearch_types::heed::RoTxn;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use meilisearch_types::milli::score_details::{ScoreDetails, ScoringStrategy};
|
||||
use meilisearch_types::milli::score_details::{self, ScoreDetails, ScoringStrategy};
|
||||
use meilisearch_types::milli::{FacetValueHit, OrderBy, SearchForFacetValues, VectorQuery};
|
||||
use meilisearch_types::settings::DEFAULT_PAGINATION_MAX_TOTAL_HITS;
|
||||
use meilisearch_types::{milli, Document};
|
||||
|
@ -562,8 +562,17 @@ pub fn perform_search(
|
|||
insert_geo_distance(sort, &mut document);
|
||||
}
|
||||
|
||||
/// FIXME: remove this or set to value from the score details
|
||||
let semantic_score = None;
|
||||
let mut semantic_score = None;
|
||||
for details in &score {
|
||||
if let ScoreDetails::Vector(score_details::Vector {
|
||||
target_vector: _,
|
||||
value_similarity: Some((_matching_vector, similarity)),
|
||||
}) = details
|
||||
{
|
||||
semantic_score = Some(*similarity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let ranking_score =
|
||||
query.show_ranking_score.then(|| ScoreDetails::global_score(score.iter()));
|
||||
|
@ -648,8 +657,10 @@ pub fn perform_search(
|
|||
hits: documents,
|
||||
hits_info,
|
||||
query: query.q.unwrap_or_default(),
|
||||
// FIXME: display input vector
|
||||
vector: None,
|
||||
vector: match query.vector {
|
||||
Some(VectorQuery::Vector(vector)) => Some(vector),
|
||||
_ => None,
|
||||
},
|
||||
processing_time_ms: before_search.elapsed().as_millis(),
|
||||
facet_distribution,
|
||||
facet_stats,
|
||||
|
|
|
@ -77,7 +77,8 @@ async fn import_dump_v1_movie_raw() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -238,7 +239,8 @@ async fn import_dump_v1_movie_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -385,7 +387,8 @@ async fn import_dump_v1_rubygems_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -518,7 +521,8 @@ async fn import_dump_v2_movie_raw() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -663,7 +667,8 @@ async fn import_dump_v2_movie_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -807,7 +812,8 @@ async fn import_dump_v2_rubygems_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -940,7 +946,8 @@ async fn import_dump_v3_movie_raw() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1085,7 +1092,8 @@ async fn import_dump_v3_movie_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1229,7 +1237,8 @@ async fn import_dump_v3_rubygems_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1362,7 +1371,8 @@ async fn import_dump_v4_movie_raw() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1507,7 +1517,8 @@ async fn import_dump_v4_movie_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1651,7 +1662,8 @@ async fn import_dump_v4_rubygems_with_settings() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###
|
||||
);
|
||||
|
@ -1896,7 +1908,8 @@ async fn import_dump_v6_containing_experimental_features() {
|
|||
},
|
||||
"pagination": {
|
||||
"maxTotalHits": 1000
|
||||
}
|
||||
},
|
||||
"embedders": {}
|
||||
}
|
||||
"###);
|
||||
|
||||
|
|
|
@ -876,7 +876,31 @@ async fn experimental_feature_vector_store() {
|
|||
}))
|
||||
.await;
|
||||
meili_snap::snapshot!(code, @"200 OK");
|
||||
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @"[]");
|
||||
// vector search returns all documents that don't have vectors in the last bucket, like all sorts
|
||||
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###"
|
||||
[
|
||||
{
|
||||
"title": "Shazam!",
|
||||
"id": "287947"
|
||||
},
|
||||
{
|
||||
"title": "Captain Marvel",
|
||||
"id": "299537"
|
||||
},
|
||||
{
|
||||
"title": "Escape Room",
|
||||
"id": "522681"
|
||||
},
|
||||
{
|
||||
"title": "How to Train Your Dragon: The Hidden World",
|
||||
"id": "166428"
|
||||
},
|
||||
{
|
||||
"title": "Gläss",
|
||||
"id": "450465"
|
||||
}
|
||||
]
|
||||
"###);
|
||||
}
|
||||
|
||||
#[cfg(feature = "default")]
|
||||
|
|
|
@ -54,7 +54,7 @@ async fn get_settings() {
|
|||
let (response, code) = index.settings().await;
|
||||
assert_eq!(code, 200);
|
||||
let settings = response.as_object().unwrap();
|
||||
assert_eq!(settings.keys().len(), 15);
|
||||
assert_eq!(settings.keys().len(), 16);
|
||||
assert_eq!(settings["displayedAttributes"], json!(["*"]));
|
||||
assert_eq!(settings["searchableAttributes"], json!(["*"]));
|
||||
assert_eq!(settings["filterableAttributes"], json!([]));
|
||||
|
@ -83,6 +83,7 @@ async fn get_settings() {
|
|||
"maxTotalHits": 1000,
|
||||
})
|
||||
);
|
||||
assert_eq!(settings["embedders"], json!({}));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue