# 组织集合

本文将讨论将文档组织到一个或多个集合中的不同方法,以及需要考虑的权衡因素。

# 层次结构

在Typesense中,一个集群可以包含一个或多个节点,每个节点存储发送到集群的整个数据集的完全副本。

一个集群可以包含一个或多个集合,而一个集合可以包含许多共享相同/相似结构(字段/属性)的文档。

例如,假设您有一个CRM系统,存储人员和公司的详细信息。 要将这些数据存储在Typesense中,您可以创建:

  • 一个名为people的集合,存储包含人员信息的单个文档(例如:nametitlecompany_name等属性)
  • 一个名为companies的集合,存储包含公司信息的单个文档(例如:namelocationnum_employees等属性)。

以下是这种层次结构的可视化表示:

[Typesense集群] ===包含多个===> [集合] ===包含多个===> [文档] ===包含多个===> [属性/字段]

注意

在Typesense Cloud中,还有一个额外的层次级别。

一个用户可以拥有多个账户(例如,当您属于多个团队时),一个账户可以拥有多个集群,其余层次结构与上述相同。

[用户] ===包含多个===> [账户] ===包含多个===> [Typesense集群] ===包含多个===> [集合] ===包含多个===> [文档] ===包含多个===> [属性/字段]

# 单集合 vs 多集合

通常我们建议为每种文档/记录类型创建一个单独的集合。 可以将集合类比为关系型数据库中的表来理解。

例如,如果您运营一个电商网站,需要支持用户搜索产品和博客文章, 那么应该创建两个集合:

  • products 集合用于存储所有商品记录
  • blog_articles 集合用于存储所有博客文章

即使像手机和冰箱这样属性差异较大的商品,仍然可以放在同一个 products 集合中。 您可以在集合模式中将非共有字段设置为可选属性。

# 开发/预发布/生产环境管理

对于不同应用环境的数据管理,您可以选择以下两种方案之一:

方案一: 为每个环境搭建独立的集群。 这种方式提供了最大的灵活性,能实现环境间的完全隔离。 同时便于在新版本 Typesense 上线生产环境前,在其他环境中进行充分测试。 代价是需要为每个环境管理多套集群的 API 密钥和集合配置,且需承担额外的集群费用。

方法二: 你可以使用单个集群,但创建带后缀的独立集合。 例如:collectionx_productioncollectionx_staging 等。 然后你可以为每个环境创建独立的 API 密钥并隔离访问权限。

现在,如果你在 staging 环境完全镜像生产数据,这种方法成本会更高,因为如果你为单个集群开启了高可用性(High Availability),你将需要为 staging 和生产数据支付更多的内存费用。 而使用方法一,你可以在 staging 集群关闭 HA 来节省成本。 但如果你在 staging 环境只保留数据的子集,那么方法二会更经济实惠。

# 多租户应用

假设你有一个社交媒体应用,你希望限制用户只能搜索自己好友的名字。

你可以在 Typesense 中将所有用户存储在一个名为 users 的集合中,每个用户文档包含一个名为 friends_with_user_ids 的数组属性。 然后你可以为每个用户生成独立的 限定搜索 API 密钥,并限制该密钥只能访问 friends_with_user_ids 属性中包含该用户 ID 的记录。

实际上,每个用户只能在存储所有用户记录的更大集合中搜索/访问自己的数据。

# 分片集合(Sharding Collections)

Typesense 经过测试并被用户报告可用于处理单集合数亿级别的文档量。

然而,随着集合中文档数量的增加和/或筛选条件的复杂度提升,搜索响应时间往往与集合规模呈正相关关系。 这与关系型数据库中表规模对大规模查询处理时间的影响非常相似。

如果您在 Typesense 中遇到大规模读写性能问题, 一个有效的优化方案是使用诸如 user_idcreated_atcountry 等属性将单一集合分片为多个集合。 例如,您可以创建 users_usausers_canadausers_uk 等集合,将不同国家的用户数据分别存放。 或者创建 users_1users_2...users_n 等集合,通过 user_id mod n 运算将用户分配到对应集合。

另一个典型场景是多租户应用——当某个特定用户的数据量异常庞大时, 您可以将该用户数据迁移至新集合,同时保持其他用户数据在主集合中。

# 单集群 vs 多集群

以下场景中采用多集群架构可能更具优势:

多环境部署:详见前文说明

多租户应用:在多租户环境中, 出于性能考量或合规要求(或两者兼有), 您可以将特定用户数据部署至完全独立的 Typesense 集群。

基于使用场景:假设你有一个包含多种搜索功能的应用程序:

  • 用户搜索产品的功能
  • 用户搜索历史订单的功能
  • 用户搜索帮助文章的功能
  • 客服人员查找用户的功能

如果你不希望基础设施问题导致整个网站和内部工具的搜索功能全部瘫痪,在这种情况下,你可以为上述每个使用场景单独部署一个集群(一个集群用于产品搜索,另一个用于订单历史搜索,以此类推)。

除了独立的故障隔离边界外,另一个优势是你可以根据需要独立扩展每个集群。例如,产品搜索可能比订单历史搜索的流量更大,你就可以为前者配置更高性能的硬件。