Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

使用离群值模式对数据进行分组

在此页面上

  • 开始之前
  • 优点
  • 缺点
  • 关于此任务
  • 步骤
  • 确定异常值阈值
  • 决定如何处理异常值
  • 为异常值文档添加指示器
  • 将额外的销售存储在单独的集合中
  • 结果
  • 异常值更新
  • 了解详情

如果您的集合存储的文档大小和形状大致相同,则完全不同的文档(异常值)可能会导致常见查询出现性能问题。

考虑一个存储数组字段的集合。如果某个文档包含的数组元素比集合中的其他文档多得多,那么您可能需要在模式中以不同方式处理该文档。

使用异常值模式将不符合预期形状的文档与集合的其余文档隔离开来。您的模式仍保留所有同样的数据,但常用查询不受单个大文档的影响。

在修改模式以处理异常值之前,请考虑异常值模式的利弊:

异常值模式可提高常用查询的性能。返回典型文档的查询不需要同时返回大型异常文档。

离群值模式还能处理应用程序中的边缘情况。例如,如果应用程序通常显示数组中的 50 个结果,则不会有包含 2,000 个结果的文档,以免影响用户体验。

离群值模式需要更复杂的逻辑来处理更新。 如果您经常需要更新数据,则可能需要考虑其他模式设计模式。 有关详细信息,请参阅离群值更新。

考虑一个追踪图书销售的模式。集合中的典型文档如下所示:

db.sales.insertOne(
{
"_id": 1,
"title": "Invisible Cities",
"year": 1972,
"author": "Italo Calvino",
"customers_purchased": [ "user00", "user01", "user02" ]
}
)

customers_purchased数组是无界数组,这意味着随着购买图书的客户数量增加,数组会变大。 对于大多数文档,这不是问题,因为商店对特定书籍的销量期望不会很高。

假设一本新的热门图书引发大量购买。当前的模式设计会导致文档臃肿,从而对性能产生负面影响。要解决此问题,请对没有典型销售量的文档实施异常值模式。

1

根据模式的典型文档结构,确定文档在何种情况下会变成异常值。该阈值可能基于应用程序用户界面的要求,或者您对文档运行的查询。

在此示例中,销量超过 50 的图书为异常值。

2

处理大型数组时,应对异常值的常用方法是将超过阈值的值存储在单独的集合中。对于销量超过 50 册的图书,将多余的 customers_purchased 值存储在单独的集合中。

3

对于销量超过 50 册的图书,添加一个名为 has_extras 的新文档字段,并将其值设置为 true。此字段表示有更多销售存储在单独的集合中。

db.sales.insertOne(
{
"_id": 2,
"title": "The Wooden Amulet",
"year": 2023,
"author": "Lesley Moreno",
"customers_purchased": [ "user00", "user01", "user02", ... "user49" ],
"has_extras": true
}
)
4

创建一个名为 extra_sales 的集合来存储超过初始 50 的销售。通过引用将 extra_sales 集合中的文档关联到 sales 集合:

db.extra_sales.insertOne(
{
"book_id": 2,
"customers_purchased_extra": [ "user50", "user51", "user52", ... "user999" ]
}
)

异常值模式可防止非典型文档影响查询性能。生成的模式避免了集合中出现大型文档,同时维护了完整的销售列表。

考虑一个应用程序页面,它显示有关图书和购买该图书的所有用户的信息。实施异常值模式后,页面会快速显示大多数图书(典型文档)的信息。

对于热门图书(异常值),应用程序会在 extra_sales 集合中对 book_id 执行额外的查询。若要提高此查询的性能,可以在 book_id 字段上创建索引。

您需要以不同于典型文档的方式处理异常文档的更新。用于执行更新的逻辑取决于您的模式设计。

要对上述模式的异常值执行更新,请实现以下应用程序逻辑:

  • 检查正在更新的文档是否已将 has_extras 设置为 true

    • 如果 has_extras 缺失或为 false,则将新增购买添加到 sales 集合中。

      • 如果生成的 customers_purchased 数组包含的元素超过 50 个,则将 has_extras 设置为 true

    • 如果 has_extrastrue,则将新增购买添加到相应 book_idsales_extras 集合中。

  • 使用桶模式对数据进行分组

  • 避免无界数组

  • 嵌入式数据与引用

  • 存储计算数据

后退

桶模式