数据类型
了解 Meilisearch 如何处理不同数据类型:字符串、数值、布尔值、数组和对象。
本文解释了 Meilisearch 如何处理数据集中不同类型的数据。
此处描述的行为仅涉及 Meilisearch 的内部流程,有助于理解分词器的工作原理。在大多数与 Meilisearch 内部工作无关的实际用途中,文档字段保持不变。
字符串
字符串是 Meilisearch 中用于索引数据的主要类型。它能够创建可搜索的内容。字符串的处理方式如下所述。
字符串分词是将字符串拆分为称为标记的单个术语列表的过程。
一个字符串被传递给分词器,然后被分解成单独的字符串标记。一个标记是一个词。
分词
分词依赖于两个主要过程来识别词并将其分离成标记:分隔符和字典。
分隔符
分隔符是表示一个词结束而另一个词开始的字符。例如,在使用拉丁字母的语言中,词通常由空格分隔。在日语中,词的边界通常以其他方式表示,例如在词尾附加に
和で
等助词。
Meilisearch 中有两种分隔符:软分隔符和硬分隔符。硬分隔符表示重要的上下文切换,例如新句子或段落。软分隔符只分隔一个词与另一个词,但不表示主题的重大变化。
以下列表显示了使用拉丁字母的语言中最常见的一些分隔符
- 软空格(距离:1):空格、引号、
'-' | '_' | '\'' | ':' | '/' | '\\' | '@' | '"' | '+' | '~' | '=' | '^' | '*' | '#'
- 硬空格(距离:8):
'.' | ';' | ',' | '!' | '?' | '(' | ')' | '[' | ']' | '{' | '}'| '|'
有关更多分隔符,包括在西里尔字母和泰语等其他书写系统中使用的分隔符,请查阅此详尽列表。
字典
对于分词过程,字典是应被视为单个术语的字符组列表。字典在识别日语等语言中的词时特别有用,因为这些语言中的词不总是由分隔符标记标记。
Meilisearch 附带了一些用于其官方支持语言的通用字典。当处理包含许多特定领域术语的文档时,例如法律文档或学术论文,提供自定义字典可能会提高搜索结果的相关性。
距离
距离在确定文档是否相关方面起着至关重要的作用,因为其中一个排名规则是邻近度规则。邻近度规则根据匹配查询词之间的距离从小到大排序结果。因此,由软空格分隔的两个词比由硬空格分隔的两个词更近,因此被认为更相关。
分词过程完成后,每个词都会被索引并存储在相应索引的全局字典中。
示例
为了演示字符串如何按空格拆分,假设您有以下字符串作为输入
在上面的示例中,Bruce
和 Willis
之间的距离等于 1。Vin
和 Diesel
之间的距离也等于 1。然而,Willis
和 Vin
之间的距离等于 8。同样的计算也适用于 Bruce
和 Diesel
(10)、Bruce
和 Vin
(9),以及 Willis
和 Diesel
(9)。
让我们看另一个例子。给定两个文档
当查询Bruce Willis
时,002
将是第一个返回的文档,而001
将是第二个。发生这种情况是因为在文档002
中,Bruce
和Willis
之间的邻近距离等于2,而在文档001
中,Bruce
和Willis
之间的距离等于8,因为句号字符.
是一个硬空格。
数值
数值类型(integer
,float
)被转换为人类可读的十进制数字字符串表示。数值类型可以被搜索,因为它们被转换为字符串。
您可以添加自定义排名规则,以在文档中具有数值的给定属性上创建升序或降序排序规则。
您还可以创建过滤器。>
、>=
、<
、<=
和TO
关系运算符仅适用于数值。
布尔值
布尔值,即true
或false
,被接收并转换为小写的人类可读文本(true
和false
)。布尔值可以被搜索,因为它们被转换为字符串。
null
null
类型可以推送到 Meilisearch 中,但它不会被纳入索引。
数组
数组是值的有序列表。这些值可以是任何类型:数字、字符串、布尔值、对象,甚至是其他数组。
Meilisearch 会展平数组并将它们连接成字符串。非字符串值将按照本文前面部分的描述进行转换。
示例
以下输入
将按所有元素排列在同一级别的方式进行处理
一旦上述数组被展平,它将完全按照字符串示例中所述的方式进行解析。
对象
当文档字段包含一个对象时,Meilisearch 会将其展平,并将对象的键和值提升到文档本身的根级别。
请记住,此处表示的展平对象是内部流程的中间快照。搜索时,返回的文档将保持其原始结构。
在下面的示例中,patient_name
键包含一个对象
在索引期间,Meilisearch 使用点符号来消除嵌套字段
使用点符号,无论嵌套深度如何,展平嵌套对象时都不会丢失信息。
假设上面的示例文档包含一个额外的对象address
,其中包含家庭和工作地址,而它们本身都是对象。展平后,文档将如下所示
Meilisearch 的内部展平过程也消除了对象数组中的嵌套。在这种情况下,值按键分组。考虑以下文档
展平后,它将如下所示
一旦文档中的所有对象都被展平,Meilisearch 将继续按照前面章节的描述对其进行处理。例如,数组将被展平,数值和布尔值将被转换为字符串。
嵌套文档查询和子文档
Meilisearch 没有子文档的概念,也无法执行嵌套文档查询。在前面的示例中,当展平appointments
数组时,约会日期和医生之间的关系丢失了
这可能导致搜索时出现意想不到的行为。以下数据集显示了两名患者及其各自的预约
以下查询返回患者0
和1
Meilisearch 无法仅返回在 2022-01-01
与 Jester Lavorre
有预约的患者。相反,它返回与 Jester Lavorre
有预约的患者,以及在 2022-01-01
有预约的患者。
解决此限制的最佳方法是重新格式化数据。上面的示例可以通过将预约数据合并到新的appointmentsMerged
字段中来解决,这样预约和医生之间的关系得以保持完整
可能的分词问题
即使分词过程的行为完全符合预期,在某些情况下也可能导致反直觉的结果,例如
对于上述两个字符串,句点.
将被视为硬空格。
10,3
将被拆分成两个字符串——10
和3
——而不是作为数字类型处理。