您是否以智能方式建立索引?
将文档添加到 Meilisearch 是否花费太长时间?了解您可以采取哪些措施来加快索引过程。

如果您刚刚使用我们的快速入门指南的 电影数据集 试用过 Meilisearch,那么索引数据可能只花费了 Meilisearch 几秒钟。但是,如果您处理的是更大的数据集,则可能花费了更长的时间。在本文中,我们将回顾最佳实践,以帮助您高效地索引数据并加快索引过程。
定义您的需求
Meilisearch 以离散记录的形式存储数据,称为文档,每个文档都必须有一个唯一的标识符——主键。文档被分组到集合中,称为索引。
为了提供即时搜索体验,Meilisearch 需要以多种方式存储和组织数据,以便以最有效的方式检索数据。因此,文档在准备好被搜索之前必须经过彻底的处理。
在 Meilisearch 中,每个索引大约有 20 个数据结构,构建它们是索引过程中最耗时的部分。更改索引设置可能会使许多这些数据结构失效,并需要重新索引您的数据。因此,通常最好在添加文档之前定义索引设置。
可搜索属性
默认情况下,添加到 Meilisearch 的所有文档字段都是可搜索的。但是,可搜索属性列表中列出的字段中的词语是最需要数据结构的——确切地说是 11 个。加快索引速度的一个好方法是确保可搜索属性列表中的所有属性都是您真正想要检查以匹配查询词语的属性。
例如,假设一个文档包含一个带有图像 URL 的字段。您可能想要向用户显示图像,但我怀疑用户是否有兴趣在 URL 中搜索查询词语。不要忘记,并非所有显示的字段都需要是可搜索的!
在可搜索属性列表中指定实际需要的字段不仅重要,而且避免在可搜索字段中包含无意义、随机或唯一的值也至关重要。想象一下所有充满“https”、“www”、“com”或“I77lHE”之类值的数据库——当试图找到特定的产品或电影时,这些值并不是很有用 😱
说到这里:🤔唯一值……这是否让您想起了什么?💡主键!这是您可以安全地从可搜索属性列表中删除的另一个字段。
底层原理
为了更好地理解自定义可搜索属性索引设置的重要性,让我们看一下可搜索属性所需的最大数据结构。在我们提到的 11 个数据结构中,有 3 个构建时间最长:WORD_DOCIDS
、WORD_POSITION_DOCID
和 WORD_PAIR_PROXIMITY_DOCIDS
。
为了更好地理解每个数据结构的工作原理,我们将使用以下文档集作为示例
{ "id": 1, "description": "New York City is the most populous city in the USA" }, { "id": 2, "description": "New York was named in honor of the Duke of York" }, { "id": 3, "description": "Tel Aviv is the new most expensive city in the world" }
在 WORD_DOCIDS
中,每个词语都与包含它的文档的主键相关联
“new” => [1, 2, 3]
“york” => [1, 2]
在 WORD_POSITION_DOCID
中,键是词语及其在文档中的位置。与键关联的值是此词语占据相同位置的文档。在上面的文档中,id
将是属性 0,而 description
将是属性 1
new(1,0) => [1, 2]
:在文档 1 和 2 中,词语“new”位于属性 1,位置 0——它是属性description
的第一个词语new(1, 4) => [3]
:在文档 3 中,“new”位于属性 1,位置 4
最后,在 WORD_PAIR_PROXIMITY_DOCIDS
中,Meilisearch 跟踪索引中所有文档中词语对之间的距离。词语必须在彼此 8 个词语的范围内才能被存储,因为更远的词语不被认为是同一上下文的一部分,因此不相关。
在上面的示例文档中,Meilisearch 将存储以下词语对
newyork1 => [1, 2]
newcity2 => [1]
newcity3 => [3]
附加到词语对的数字表示它们之间的距离
- 1 表示词语彼此相邻
- 2 表示它们之间隔着一个词语
- 3 表示它们之间隔着两个词语
如您所见,每个新词语都代表 Meilisearch 内部数据结构中的额外行。像唯一 ID 或 URL 字符串这样的值可能会使数据库急剧增长——而且很可能是没有必要的。
精简 Meilisearch 应该搜索哪些字段对于缩短索引时间至关重要。它还可以提高相关性和搜索速度,因为结果不会被不相关的数据污染。
可过滤和可排序属性
某些字段不包含任何词语,但可能仍然对于帮助用户找到他们需要的结果至关重要。这种类型的数据可能更适合用于过滤和排序,而不是常规的基于文本的搜索。
可过滤属性是可以用作过滤器来优化搜索结果的属性。您可以使用它们来限制特定用户的搜索结果,或创建分面搜索界面,允许用户根据他们选择的标准缩小结果列表。布尔类型的值是很好的过滤器。
可排序属性是可以用于在搜索时进行排序的属性,这允许用户决定他们希望首先看到哪些文档。数值非常适合排序。
根据经验,如果您的数据集包含具有数值和布尔字段值的文档,请花时间评估它们是否可以成为可过滤或可排序属性列表的一部分。
排名规则
排名规则负责搜索结果的相关性。Meilisearch 包含六个内置排名规则
[ "words", "typo", "proximity", "attribute", "sort", "exactness" ]
您还可以向此列表添加自定义规则以进行升序和降序排序
[ "words", "typo", "proximity", "attribute", "sort", "exactness", "price:asc" ]
与用于在搜索时排序的可排序属性不同,自定义排名规则用于设置默认顺序。
如果您需要这种默认排序,最好提前配置它。在文档已被索引后添加新规则将触发重新索引,并可能让您感到恼火!
缩小尺寸并批量处理
仅索引您真正需要的。数据库中的所有列都是必要的吗?数据集中的列越少,文档就越小。文档越小,它们的重量就越轻,它们到达 Meilisearch 的速度就越快,然后 Meilisearch 就能更快地处理它们。
Meilisearch 将连续的文档添加请求组合成一个批次并一起处理。这大大加快了索引过程。由于每个批次的最终大小将取决于 Meilisearch 在处理最新的文档添加请求时接收到的数据量,因此建议以组而不是逐个发送文档。
出于同样的原因,请考虑压缩您的数据。Meilisearch 支持 br
、deflate
和 gzip
压缩方法。您可以在我们的文档中找到更多信息。
保持更新并让我们保持更新
使用最新的 Meilisearch 稳定版本。新版本通常包含性能改进,可以显着提高索引速度。
如果您遇到任何索引问题,请报告它们!这对于改进产品至关重要!
不要相信我,相信数据
在创建一些基准测试时,Engine 团队的软件工程师 Many 创建了以下图表。请注意,索引时间高度依赖于机器的大小(CPU、RAM)和数据集:对于大小相似的数据集,您可能会获得不同的结果。
水平轴表示数据集的大小,垂直轴表示索引时间
红线表示使用默认设置的索引时间,蓝线表示使用自定义配置的索引时间。在使用相同的机器和数据集的情况下,我们观察到使用自定义设置时索引速度提高了 36%。
我们观察到数据库大小也有类似的改进,当使用自定义设置时,数据库大小明显更小
蓝色表示使用自定义设置的数据库大小,红色表示使用默认设置的数据库大小
了解更多关于 Meilisearch 可以为您的业务带来什么
这就是目前为止的全部内容!我们介绍了加快索引过程的最佳实践。您知道这些技巧中的任何一个吗?在遵循这些技巧后,您是否注意到索引速度有所不同?在我们的 Discord 上分享您的经验!
您的反馈对于帮助我们改进 Meilisearch 至关重要!我再怎么强调也不为过,而且我永远不会厌倦重复它,因为这是事实。我们的社区与我们一起构建了 Meilisearch,并继续帮助我们塑造它。
问题或 GitHub 上的 产品讨论,我们的 路线图,我们的 Discord 服务器……无论在哪里,无论以何种方式,我们都想听到您的声音!