从 v 3.2.0 开始,Manticore Search 引入了一项新功能 - 文档存储。
历史上,Manticore Search 是一个文本搜索引擎,它索引文本但不保留原始文本。文本被处理,从普通字符串转换为形成全文索引的特殊结构,这允许快速文本搜索。在结果集中,用户并没有收到原始文本,因为从全文索引重新组合它可能是一个复杂的过程。此外,索引设置可能包括停止某些单词被索引的条款(如最小单词长度或停用词),这可能使重建变得不可能。
搜索工作流是为了在 Manticore 中执行全文搜索而创建的,并基于结果集在数据的原始来源(数据库或文件)中执行额外查找,以检索仅在 Manticore 中索引的内容。在某些情况下,额外的查找是必需的,以检索不仅是“缺失”的文本,还有其他未包含在索引中的数据,因为它在搜索操作中未被使用,而这些数据只会增加(不必要地)索引大小。但在许多情况下,查找的唯一目的是获取“缺失”的文本,这被视为一个额外的步骤,最好消除 - 因为这意味着简化应用程序代码,避免额外的负载、资源消耗和数据存储的另一个故障点。
还有一些场景,其中原始数据不在传统数据库中,并且在查询时从数据中检索原始文本可能会很慢。要求将这些数据存储在数据库中可能被视为不必要的,并且是使用数据库的唯一原因,以补偿搜索引擎无法存储原始内容的能力。这些场景可以是:
- 一家公司可能希望能够搜索办公文档中的文本,如 Word 或 PDF - 这些可以是内部工具或提供科学、法律或技术论文的门户的一部分。
- 数据来自网络服务或爬取的页面
- 流数据可以是日志、消息或电子邮件。从源读取这些数据可能很困难,因为在许多情况下,它们存储在分布式系统中,并且在查询时读取它们会使应用程序代码变得复杂
您可以通过我们的 互动课程 学习如何不仅使用索引,还存储文档内容。
现在可以存储原始文本并在结果中检索它们。
我们应该提到,DS 功能并不使 Manticore 成为传统数据库。Manticore 支持事务和 binlog 恢复,虽然它提供了大多数 ACID 属性,但不被视为真正的 ACID 兼容数据库。
目前也没有存储加密。敏感或关键数据,如用户凭据或支付交易,不被视为适合存储在 Manticore 中。此外,传统数据库的一些功能,如 JOINs,目前尚不支持。但我们将在未来的版本中对此进行改进。
尽管如此,在许多情况下,仅使用 Manticore 存储数据或存储而不执行额外查找是非常有意义的。
文档存储可以减少对原始数据仓库的工作负载或减少空间需求。
在撰写本文时,文档存储的性能也是一个方面。但我们预计在下一个版本中大大改善这一方面。
使用
可以使用 stored_fields 索引指令启用存储,该指令接受用逗号分隔的字段名称列表。
index myindex {
type = rt
path = /path/to/myindex
rt_field = title
rt_field = short_description
rt_field = long_description
rt_attr_string = title
rt_attr_uint = group_id
stored_fields = short_description, long_description
}
没有存储字段的结果看起来像:
mysql> SELECT * FROM myindex WHERE ....\G
*************************** 1. row ***************************
id: 11
title: A title goes here
group_id:100
*************************** 2. row ***************************
...
有存储字段:
mysql> SELECT * FROM myindex WHERE ....\G
*************************** 1. row ***************************
id: 11
title: A title goes here
short_description: A short text description
goes here
long_description: A long text description
can be found here
group_id:100
*************************** 2. row ***************************
...
在我们的 docstore 课程 中可以看到带有和不带有文档存储的索引之间的展示。
高级调优
文本存储在磁盘上的单独文件中。默认情况下,它们使用 lz4 算法进行压缩。可用的替代 lz4hc 算法,或者通过设置 'docstore_compression' 索引指令可以禁用压缩('none')。对于 'lz4hc' 算法,可以通过 docstore_compression_level 索引指令调整压缩级别,该指令可以取值从 1 到 12(默认值为 9)。文本在磁盘上以块的形式压缩。块大小可以通过 docstore_block_size 指令进行调整。默认值为 16k。增加块大小将改善压缩比并节省更多磁盘空间,而减小块大小应提高访问速度。
当搜索需要从存储中获取文本时,包含该文本的块将从磁盘读取并解压缩。由于一个块可能包含来自多个文档的文本,因此可以将解压缩的块缓存到内存中。默认情况下,使用的是全守护进程 16MB 的缓存。缓存大小可以通过 searchd 的 docstore_cache_size 设置进行调整。
与字符串属性的区别
Manticore Search 已经具有一种 数据类型 ,能够存储和检索结果集中的文本,并且还可以用于比较、正则过滤、排序和聚合操作。更重要的是,在实时索引的情况下,可以对全文字段和字符串属性使用相同的名称。关于存储字段的目的存在一个问题。
字符串属性存储在 Manticore Search 3 索引的 blob 组件中,该组件还包含 JSON 和 MVA 属性。对 blob 组件的读取通过 mmap() 管理,可以保留在磁盘上并根据需要读取,或者在索引加载时完全读取和加载,或者读取、加载并锁定在内存中。字符串属性中的文本以未压缩的形式存储。如果以这种方式存储的文本很长(如描述、文章内容),它们可能会占用大量磁盘空间,并且还会增加文档的 blob 组件所使用的内存。对于之前未能完全适应 RAM 的索引,作为字符串属性添加长文本意味着 更少 的可变长度属性(字符串、JSON、MVA)可以缓存到 RAM 中,从而导致性能不佳。由于大小增加,可能无法在内存中锁定 blob 组件(access_blob_attrs=mlock)。字符串属性应仅用于短文本,预计将执行非全文过滤、分组和排序操作,而不仅仅是检索。
另一方面,存储字段是一个单独的组件。文本仅从磁盘读取,如果有可用的 RAM,可以将 docstore_cache_size 设置为较高的值(GB)以在 RAM 中缓存存储字段。此外,存储字段默认是压缩的,占用的存储空间比字符串属性少。还有一些情况需要将文本存储在索引中,并且它们仅在输出时使用,根本不用于过滤/排序/分组。从资源管理的角度来看,将它们放在 blob 中并不是最佳选择。这类字符串的例子可以是产品代码或 UUID(它们应该是唯一的,对它们进行排序没有太大意义)。将它们移动到存储字段将使 blob 更小,意味着使用更少的 RAM,启动时加载更快,并且根据情况,允许 mlocking。这里可能出现的一个“问题”是,新字段可能在不搜索特定字段的全文匹配中发挥作用,因此使用 ignore field search operator 排除它们被搜索可能是个好主意。
