mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-09-06 20:56:31 +00:00
Add support for ugly names
This commit is contained in:
@ -18,7 +18,7 @@ use nom::sequence::{terminated, tuple};
|
|||||||
use Condition::*;
|
use Condition::*;
|
||||||
|
|
||||||
use crate::error::IResultExt;
|
use crate::error::IResultExt;
|
||||||
use crate::value::parse_vector_value;
|
use crate::value::parse_dotted_value_part;
|
||||||
use crate::ErrorKind;
|
use crate::ErrorKind;
|
||||||
use crate::VectorFilter;
|
use crate::VectorFilter;
|
||||||
use crate::{parse_value, FilterCondition, IResult, Span, Token};
|
use crate::{parse_value, FilterCondition, IResult, Span, Token};
|
||||||
@ -136,13 +136,13 @@ fn parse_vectors(input: Span) -> IResult<(Token, Option<Token>, VectorFilter<'_>
|
|||||||
// We could use nom's `cut` but it's better to be explicit about the errors
|
// We could use nom's `cut` but it's better to be explicit about the errors
|
||||||
|
|
||||||
let (input, embedder_name) =
|
let (input, embedder_name) =
|
||||||
parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidEmbedder)?;
|
parse_dotted_value_part(input).map_cut(ErrorKind::VectorFilterInvalidEmbedder)?;
|
||||||
|
|
||||||
let (input, filter) = alt((
|
let (input, filter) = alt((
|
||||||
map(
|
map(
|
||||||
preceded(tag(".fragments"), |input| {
|
preceded(tag(".fragments"), |input| {
|
||||||
let (input, _) = tag(".")(input).map_cut(ErrorKind::VectorFilterMissingFragment)?;
|
let (input, _) = tag(".")(input).map_cut(ErrorKind::VectorFilterMissingFragment)?;
|
||||||
parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidFragment)
|
parse_dotted_value_part(input).map_cut(ErrorKind::VectorFilterInvalidFragment)
|
||||||
}),
|
}),
|
||||||
VectorFilter::Fragment,
|
VectorFilter::Fragment,
|
||||||
),
|
),
|
||||||
|
@ -61,7 +61,9 @@ use nom::multi::{many0, separated_list1};
|
|||||||
use nom::number::complete::recognize_float;
|
use nom::number::complete::recognize_float;
|
||||||
use nom::sequence::{delimited, preceded, terminated, tuple};
|
use nom::sequence::{delimited, preceded, terminated, tuple};
|
||||||
use nom::Finish;
|
use nom::Finish;
|
||||||
|
pub use nom::Slice;
|
||||||
use nom_locate::LocatedSpan;
|
use nom_locate::LocatedSpan;
|
||||||
|
pub use value::parse_dotted_value_part;
|
||||||
pub(crate) use value::parse_value;
|
pub(crate) use value::parse_value;
|
||||||
use value::word_exact;
|
use value::word_exact;
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ pub fn word_exact<'a, 'b: 'a>(tag: &'b str) -> impl Fn(Span<'a>) -> IResult<'a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// vector_value = ( non_dot_word | singleQuoted | doubleQuoted)
|
/// dotted_value_part = ( non_dot_word | singleQuoted | doubleQuoted)
|
||||||
pub fn parse_vector_value(input: Span) -> IResult<Token> {
|
pub fn parse_dotted_value_part(input: Span) -> IResult<Token> {
|
||||||
pub fn non_dot_word(input: Span) -> IResult<Token> {
|
pub fn non_dot_word(input: Span) -> IResult<Token> {
|
||||||
let (input, word) = take_while1(|c| is_value_component(c) && c != '.')(input)?;
|
let (input, word) = take_while1(|c| is_value_component(c) && c != '.')(input)?;
|
||||||
Ok((input, word.into()))
|
Ok((input, word.into()))
|
||||||
|
@ -20,6 +20,7 @@ use meilisearch_types::milli::prompt::{get_document, get_inline_document_fields}
|
|||||||
use meilisearch_types::milli::vector::db::IndexEmbeddingConfig;
|
use meilisearch_types::milli::vector::db::IndexEmbeddingConfig;
|
||||||
use meilisearch_types::milli::vector::json_template::{self, JsonTemplate};
|
use meilisearch_types::milli::vector::json_template::{self, JsonTemplate};
|
||||||
use meilisearch_types::milli::vector::EmbedderOptions;
|
use meilisearch_types::milli::vector::EmbedderOptions;
|
||||||
|
use meilisearch_types::milli::{Span, Token};
|
||||||
use meilisearch_types::{heed, milli, Index};
|
use meilisearch_types::{heed, milli, Index};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@ -133,47 +134,49 @@ impl FragmentKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RenderError {
|
enum RenderError<'a> {
|
||||||
MultipleTemplates,
|
MultipleTemplates,
|
||||||
MissingTemplate,
|
MissingTemplate,
|
||||||
EmptyTemplateId,
|
EmptyTemplateId,
|
||||||
UnknownTemplateRoot(String),
|
UnknownTemplateRoot(Token<'a>),
|
||||||
MissingEmbedderName {
|
MissingEmbedderName {
|
||||||
available: Vec<String>,
|
available: Vec<String>,
|
||||||
},
|
},
|
||||||
EmbedderDoesNotExist {
|
EmbedderDoesNotExist {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
available: Vec<String>,
|
available: Vec<String>,
|
||||||
},
|
},
|
||||||
EmbedderUsesFragments {
|
EmbedderUsesFragments {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
},
|
},
|
||||||
MissingTemplateAfterEmbedder {
|
MissingTemplateAfterEmbedder {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
indexing: Vec<String>,
|
indexing: Vec<String>,
|
||||||
search: Vec<String>,
|
search: Vec<String>,
|
||||||
},
|
},
|
||||||
UnknownTemplatePrefix {
|
UnknownTemplatePrefix {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
found: String,
|
found: Token<'a>,
|
||||||
indexing: Vec<String>,
|
indexing: Vec<String>,
|
||||||
search: Vec<String>,
|
search: Vec<String>,
|
||||||
},
|
},
|
||||||
ReponseError(ResponseError),
|
ReponseError(ResponseError),
|
||||||
MissingFragment {
|
MissingFragment {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
kind: FragmentKind,
|
kind: FragmentKind,
|
||||||
available: Vec<String>,
|
available: Vec<String>,
|
||||||
},
|
},
|
||||||
FragmentDoesNotExist {
|
FragmentDoesNotExist {
|
||||||
embedder: String,
|
embedder: Token<'a>,
|
||||||
fragment: String,
|
fragment: Token<'a>,
|
||||||
kind: FragmentKind,
|
kind: FragmentKind,
|
||||||
available: Vec<String>,
|
available: Vec<String>,
|
||||||
},
|
},
|
||||||
LeftOverToken(String),
|
LeftOverToken(Token<'a>),
|
||||||
MissingChatCompletionTemplate,
|
MissingChatCompletionTemplate,
|
||||||
UnknownChatCompletionTemplate(String),
|
UnknownChatCompletionTemplate(Token<'a>),
|
||||||
|
ExpectedDotAfterValue(milli::Span<'a>),
|
||||||
|
ExpectedValue(milli::Span<'a>),
|
||||||
|
|
||||||
DocumentNotFound(String),
|
DocumentNotFound(String),
|
||||||
BothInlineDocAndDocId,
|
BothInlineDocAndDocId,
|
||||||
@ -182,13 +185,13 @@ enum RenderError {
|
|||||||
CouldNotHandleInput,
|
CouldNotHandleInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<heed::Error> for RenderError {
|
impl From<heed::Error> for RenderError<'_> {
|
||||||
fn from(error: heed::Error) -> Self {
|
fn from(error: heed::Error) -> Self {
|
||||||
RenderError::ReponseError(error.into())
|
RenderError::ReponseError(error.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<milli::Error> for RenderError {
|
impl From<milli::Error> for RenderError<'_> {
|
||||||
fn from(error: milli::Error) -> Self {
|
fn from(error: milli::Error) -> Self {
|
||||||
RenderError::ReponseError(error.into())
|
RenderError::ReponseError(error.into())
|
||||||
}
|
}
|
||||||
@ -196,7 +199,7 @@ impl From<milli::Error> for RenderError {
|
|||||||
|
|
||||||
use RenderError::*;
|
use RenderError::*;
|
||||||
|
|
||||||
impl From<RenderError> for ResponseError {
|
impl From<RenderError<'_>> for ResponseError {
|
||||||
fn from(error: RenderError) -> Self {
|
fn from(error: RenderError) -> Self {
|
||||||
match error {
|
match error {
|
||||||
MultipleTemplates => ResponseError::from_msg(
|
MultipleTemplates => ResponseError::from_msg(
|
||||||
@ -322,31 +325,39 @@ impl From<RenderError> for ResponseError {
|
|||||||
String::from("Could not handle the input provided."),
|
String::from("Could not handle the input provided."),
|
||||||
Code::InvalidRenderInput,
|
Code::InvalidRenderInput,
|
||||||
),
|
),
|
||||||
|
ExpectedDotAfterValue(span) => ResponseError::from_msg(
|
||||||
|
format!("Expected a dot after value, but found `{span}`."),
|
||||||
|
Code::InvalidRenderTemplateId,
|
||||||
|
),
|
||||||
|
ExpectedValue(span) => ResponseError::from_msg(
|
||||||
|
format!("Expected a value, but found `{span}`."),
|
||||||
|
Code::InvalidRenderTemplateId,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_template_id_fragment(
|
fn parse_template_id_fragment<'a>(
|
||||||
name: Option<&str>,
|
name: Option<Token<'a>>,
|
||||||
kind: FragmentKind,
|
kind: FragmentKind,
|
||||||
embedding_config: &IndexEmbeddingConfig,
|
embedding_config: &IndexEmbeddingConfig,
|
||||||
embedder_name: &str,
|
embedder: Token<'a>,
|
||||||
) -> Result<serde_json::Value, RenderError> {
|
) -> Result<serde_json::Value, RenderError<'a>> {
|
||||||
let get_available =
|
let get_available =
|
||||||
[EmbedderOptions::indexing_fragments, EmbedderOptions::search_fragments][kind as usize];
|
[EmbedderOptions::indexing_fragments, EmbedderOptions::search_fragments][kind as usize];
|
||||||
let get_specific =
|
let get_specific =
|
||||||
[EmbedderOptions::indexing_fragment, EmbedderOptions::search_fragment][kind as usize];
|
[EmbedderOptions::indexing_fragment, EmbedderOptions::search_fragment][kind as usize];
|
||||||
|
|
||||||
let fragment_name = name.ok_or_else(|| MissingFragment {
|
let fragment = name.ok_or_else(|| MissingFragment {
|
||||||
embedder: embedder_name.to_string(),
|
embedder: embedder.clone(),
|
||||||
kind,
|
kind,
|
||||||
available: get_available(&embedding_config.config.embedder_options),
|
available: get_available(&embedding_config.config.embedder_options),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let fragment = get_specific(&embedding_config.config.embedder_options, fragment_name)
|
let fragment = get_specific(&embedding_config.config.embedder_options, fragment.value())
|
||||||
.ok_or_else(|| FragmentDoesNotExist {
|
.ok_or_else(|| FragmentDoesNotExist {
|
||||||
embedder: embedder_name.to_string(),
|
embedder,
|
||||||
fragment: fragment_name.to_string(),
|
fragment,
|
||||||
kind,
|
kind,
|
||||||
available: get_available(&embedding_config.config.embedder_options),
|
available: get_available(&embedding_config.config.embedder_options),
|
||||||
})?;
|
})?;
|
||||||
@ -354,83 +365,96 @@ fn parse_template_id_fragment(
|
|||||||
Ok(fragment.clone())
|
Ok(fragment.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_template_id(
|
fn parse_template_id<'a>(
|
||||||
index: &Index,
|
index: &Index,
|
||||||
rtxn: &RoTxn<'_>,
|
rtxn: &RoTxn,
|
||||||
id: &str,
|
id: &'a str,
|
||||||
) -> Result<(serde_json::Value, bool), RenderError> {
|
) -> Result<(serde_json::Value, bool), RenderError<'a>> {
|
||||||
let mut parts = id.split('.');
|
let mut input: Span = id.into();
|
||||||
|
let mut next_part = |first: bool| -> Result<Option<Token<'_>>, RenderError<'a>> {
|
||||||
|
if input.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
if !first {
|
||||||
|
if !input.starts_with('.') {
|
||||||
|
return Err(ExpectedDotAfterValue(input));
|
||||||
|
}
|
||||||
|
input = milli::filter_parser::Slice::slice(&input, 1..);
|
||||||
|
}
|
||||||
|
let (remaining, value) = milli::filter_parser::parse_dotted_value_part(input)
|
||||||
|
.map_err(|_| ExpectedValue(input))?;
|
||||||
|
input = remaining;
|
||||||
|
|
||||||
let root = parts.next().ok_or(EmptyTemplateId)?;
|
Ok(Some(value))
|
||||||
|
};
|
||||||
|
|
||||||
let template = match root {
|
let root = next_part(true)?.ok_or(EmptyTemplateId)?;
|
||||||
|
let template = match root.value() {
|
||||||
"embedders" => {
|
"embedders" => {
|
||||||
let index_embedding_configs = index.embedding_configs();
|
let index_embedding_configs = index.embedding_configs();
|
||||||
let embedding_configs = index_embedding_configs.embedding_configs(rtxn)?;
|
let embedding_configs = index_embedding_configs.embedding_configs(rtxn)?;
|
||||||
let get_embedders = || embedding_configs.iter().map(|c| c.name.clone()).collect();
|
let get_embedders = || embedding_configs.iter().map(|c| c.name.clone()).collect();
|
||||||
|
|
||||||
let embedder =
|
let embedder = next_part(false)?
|
||||||
parts.next().ok_or_else(|| MissingEmbedderName { available: get_embedders() })?;
|
.ok_or_else(|| MissingEmbedderName { available: get_embedders() })?;
|
||||||
|
|
||||||
let embedding_config = embedding_configs
|
let embedding_config = embedding_configs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|config| config.name == embedder)
|
.find(|config| config.name == embedder.value())
|
||||||
.ok_or_else(|| EmbedderDoesNotExist {
|
.ok_or_else(|| EmbedderDoesNotExist {
|
||||||
embedder: embedder.to_string(),
|
embedder: embedder.clone(),
|
||||||
available: get_embedders(),
|
available: get_embedders(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let get_indexing = || embedding_config.config.embedder_options.indexing_fragments();
|
let get_indexing = || embedding_config.config.embedder_options.indexing_fragments();
|
||||||
let get_search = || embedding_config.config.embedder_options.search_fragments();
|
let get_search = || embedding_config.config.embedder_options.search_fragments();
|
||||||
|
|
||||||
let template_kind = parts.next().ok_or_else(|| MissingTemplateAfterEmbedder {
|
let template_kind = next_part(false)?.ok_or_else(|| MissingTemplateAfterEmbedder {
|
||||||
embedder: embedder.to_string(),
|
embedder: embedder.clone(),
|
||||||
indexing: get_indexing(),
|
indexing: get_indexing(),
|
||||||
search: get_search(),
|
search: get_search(),
|
||||||
})?;
|
})?;
|
||||||
match template_kind {
|
match template_kind.value() {
|
||||||
"documentTemplate" | "documenttemplate"
|
"documentTemplate" if !embedding_config.fragments.as_slice().is_empty() => {
|
||||||
if !embedding_config.fragments.as_slice().is_empty() =>
|
return Err(EmbedderUsesFragments { embedder });
|
||||||
{
|
|
||||||
return Err(EmbedderUsesFragments { embedder: embedder.to_string() });
|
|
||||||
}
|
}
|
||||||
"documentTemplate" | "documenttemplate" => (
|
"documentTemplate" => (
|
||||||
serde_json::Value::String(embedding_config.config.prompt.template.clone()),
|
serde_json::Value::String(embedding_config.config.prompt.template.clone()),
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
"indexingFragments" | "indexingfragments" => (
|
"indexingFragments" => (
|
||||||
parse_template_id_fragment(
|
parse_template_id_fragment(
|
||||||
parts.next(),
|
next_part(false)?,
|
||||||
FragmentKind::Indexing,
|
FragmentKind::Indexing,
|
||||||
embedding_config,
|
embedding_config,
|
||||||
embedder,
|
embedder,
|
||||||
)?,
|
)?,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
"searchFragments" | "searchfragments" => (
|
"searchFragments" => (
|
||||||
parse_template_id_fragment(
|
parse_template_id_fragment(
|
||||||
parts.next(),
|
next_part(false)?,
|
||||||
FragmentKind::Search,
|
FragmentKind::Search,
|
||||||
embedding_config,
|
embedding_config,
|
||||||
embedder,
|
embedder,
|
||||||
)?,
|
)?,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
found => {
|
_ => {
|
||||||
return Err(UnknownTemplatePrefix {
|
return Err(UnknownTemplatePrefix {
|
||||||
embedder: embedder.to_string(),
|
embedder,
|
||||||
found: found.to_string(),
|
found: template_kind,
|
||||||
indexing: get_indexing(),
|
indexing: get_indexing(),
|
||||||
search: get_search(),
|
search: get_search(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"chatCompletions" | "chatcompletions" => {
|
"chatCompletions" => {
|
||||||
let template_name = parts.next().ok_or(MissingChatCompletionTemplate)?;
|
let template_name = next_part(false)?.ok_or(MissingChatCompletionTemplate)?;
|
||||||
|
|
||||||
if template_name != "documentTemplate" {
|
if template_name.value() != "documentTemplate" {
|
||||||
return Err(UnknownChatCompletionTemplate(template_name.to_string()));
|
return Err(UnknownChatCompletionTemplate(template_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
let chat_config = index.chat_config(rtxn)?;
|
let chat_config = index.chat_config(rtxn)?;
|
||||||
@ -438,26 +462,26 @@ fn parse_template_id(
|
|||||||
(serde_json::Value::String(chat_config.prompt.template.clone()), true)
|
(serde_json::Value::String(chat_config.prompt.template.clone()), true)
|
||||||
}
|
}
|
||||||
"" => return Err(EmptyTemplateId),
|
"" => return Err(EmptyTemplateId),
|
||||||
unknown => {
|
_ => {
|
||||||
return Err(UnknownTemplateRoot(unknown.to_string()));
|
return Err(UnknownTemplateRoot(root));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(next) = parts.next() {
|
if let Some(next) = next_part(false)? {
|
||||||
return Err(LeftOverToken(next.to_string()));
|
return Err(LeftOverToken(next));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(template)
|
Ok(template)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn render(index: Index, query: RenderQuery) -> Result<RenderResult, RenderError> {
|
async fn render(index: Index, query: RenderQuery) -> Result<RenderResult, ResponseError> {
|
||||||
let rtxn = index.read_txn()?;
|
let rtxn = index.read_txn()?;
|
||||||
|
|
||||||
let (template, fields_available) = match (query.template.inline, query.template.id) {
|
let (template, fields_available) = match (query.template.inline, query.template.id) {
|
||||||
(Some(inline), None) => (inline, true),
|
(Some(inline), None) => (inline, true),
|
||||||
(None, Some(id)) => parse_template_id(&index, &rtxn, &id)?,
|
(None, Some(id)) => parse_template_id(&index, &rtxn, &id)?,
|
||||||
(Some(_), Some(_)) => return Err(MultipleTemplates),
|
(Some(_), Some(_)) => return Err(MultipleTemplates.into()),
|
||||||
(None, None) => return Err(MissingTemplate),
|
(None, None) => return Err(MissingTemplate.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let fields_already_present = query
|
let fields_already_present = query
|
||||||
@ -474,7 +498,7 @@ async fn render(index: Index, query: RenderQuery) -> Result<RenderResult, Render
|
|||||||
let insert_fields =
|
let insert_fields =
|
||||||
fields_available && has_doc && fields_probably_used && !fields_already_present;
|
fields_available && has_doc && fields_probably_used && !fields_already_present;
|
||||||
if has_inline_doc && has_document_id {
|
if has_inline_doc && has_document_id {
|
||||||
return Err(BothInlineDocAndDocId);
|
return Err(BothInlineDocAndDocId.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rendered = Value::Null;
|
let mut rendered = Value::Null;
|
||||||
|
@ -26,7 +26,7 @@ async fn wrong_id_prefix() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Template ID must start with `embedders` or `chatCompletions`, but found `wrong`.",
|
"message": "Template ID must start with `embedders` or `chatCompletions`, but found `{wrong}`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -59,7 +59,7 @@ async fn wrong_embedder() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Embedder `wrong` does not exist.\n Hint: Available embedders are `rest`.",
|
"message": "Embedder `{wrong}` does not exist.\n Hint: Available embedders are `rest`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -75,7 +75,7 @@ async fn missing_template_kind() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Template ID configured with `embedders.rest` but no template kind provided.\n Hint: Available fragments are `indexingFragments.basic`, `indexingFragments.withBreed`, `searchFragments.justBreed`, `searchFragments.justName`, `searchFragments.query`.",
|
"message": "Template ID configured with `embedders.{rest}` but no template kind provided.\n Hint: Available fragments are `indexingFragments.basic`, `indexingFragments.withBreed`, `searchFragments.justBreed`, `searchFragments.justName`, `searchFragments.query`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -92,7 +92,7 @@ async fn wrong_template_kind() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Wrong template `wrong` after embedder `rest`.\n Hint: Available fragments are `indexingFragments.basic`, `indexingFragments.withBreed`, `searchFragments.justBreed`, `searchFragments.justName`, `searchFragments.query`.",
|
"message": "Wrong template `{wrong}` after embedder `{rest}`.\n Hint: Available fragments are `indexingFragments.basic`, `indexingFragments.withBreed`, `searchFragments.justBreed`, `searchFragments.justName`, `searchFragments.query`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -109,7 +109,7 @@ async fn document_template_on_fragmented_index() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Requested document template for embedder `rest` but it uses fragments.\n Hint: Use `indexingFragments` or `searchFragments` instead.",
|
"message": "Requested document template for embedder `{rest}` but it uses fragments.\n Hint: Use `indexingFragments` or `searchFragments` instead.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -126,7 +126,7 @@ async fn missing_fragment_name() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Indexing fragment name was not provided.\n Hint: Available indexing fragments for embedder `rest` are `basic`, `withBreed`.",
|
"message": "Indexing fragment name was not provided.\n Hint: Available indexing fragments for embedder `{rest}` are `basic`, `withBreed`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -138,7 +138,7 @@ async fn missing_fragment_name() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Search fragment name was not provided.\n Hint: Available search fragments for embedder `rest` are `justBreed`, `justName`, `query`.",
|
"message": "Search fragment name was not provided.\n Hint: Available search fragments for embedder `{rest}` are `justBreed`, `justName`, `query`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -156,7 +156,7 @@ async fn wrong_fragment_name() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Indexing fragment `wrong` does not exist for embedder `rest`.\n Hint: Available indexing fragments are `basic`, `withBreed`.",
|
"message": "Indexing fragment `{wrong}` does not exist for embedder `{rest}`.\n Hint: Available indexing fragments are `basic`, `withBreed`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -168,7 +168,7 @@ async fn wrong_fragment_name() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Search fragment `wrong` does not exist for embedder `rest`.\n Hint: Available search fragments are `justBreed`, `justName`, `query`.",
|
"message": "Search fragment `{wrong}` does not exist for embedder `{rest}`.\n Hint: Available search fragments are `justBreed`, `justName`, `query`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -188,7 +188,7 @@ async fn leftover_tokens() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Leftover token `leftover` after parsing template ID",
|
"message": "Leftover token `{leftover}` after parsing template ID",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -201,7 +201,7 @@ async fn leftover_tokens() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Leftover token `leftover` after parsing template ID",
|
"message": "Leftover token `{leftover}` after parsing template ID",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -214,7 +214,7 @@ async fn leftover_tokens() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Leftover token `leftover` after parsing template ID",
|
"message": "Leftover token `{leftover}` after parsing template ID",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -274,7 +274,7 @@ async fn wrong_chat_completions_template() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Unknown chat completion template ID `wrong`. The only available template is `documentTemplate`.",
|
"message": "Unknown chat completion template ID `{wrong}`. The only available template is `documentTemplate`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
@ -603,7 +603,7 @@ async fn embedder_document_template() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Wrong template `wrong` after embedder `rest`.\n Hint: Available template: `documentTemplate`.",
|
"message": "Wrong template `{wrong}` after embedder `{rest}`.\n Hint: Available template: `documentTemplate`.",
|
||||||
"code": "invalid_render_template_id",
|
"code": "invalid_render_template_id",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
"link": "https://docs.meilisearch.com/errors#invalid_render_template_id"
|
||||||
|
@ -44,6 +44,7 @@ use std::hash::BuildHasherDefault;
|
|||||||
|
|
||||||
use charabia::normalizer::{CharNormalizer, CompatibilityDecompositionNormalizer};
|
use charabia::normalizer::{CharNormalizer, CompatibilityDecompositionNormalizer};
|
||||||
pub use documents::GeoSortStrategy;
|
pub use documents::GeoSortStrategy;
|
||||||
|
pub use filter_parser;
|
||||||
pub use filter_parser::{Condition, FilterCondition, Span, Token};
|
pub use filter_parser::{Condition, FilterCondition, Span, Token};
|
||||||
use fxhash::{FxHasher32, FxHasher64};
|
use fxhash::{FxHasher32, FxHasher64};
|
||||||
pub use grenad::CompressionType;
|
pub use grenad::CompressionType;
|
||||||
|
Reference in New Issue
Block a user