子文档数组范围查询的最佳分片键(或优化查询)

Best shard key (or optimised query) for range query on sub-document array

下面是我数据库中文档的简化版本:

{
    _id : 1,
    main_data : 100,
    sub_docs: [
        {
            _id : a,
            data : 100
        },
        {
            _id: b,
            data : 200
        },
        {
            _id: c,
            data: 150
        }
    ]
}

想象一下,我有很多具有不同数据值(比如 0 - 1000)的文档。 目前我的查询是这样的:

db.myDb.find(
    { sub_docs.data : { $elemMatch: { $gte: 110, $lt: 160 } } }
)

有没有我可以用来帮助这个查询的分片键?目前它正在查询所有分片。 如果没有,是否有更好的方法来构建我的查询?

杰克逊,

您正在以正确的方式思考这个问题。 MongoDB 中广播查询的问题是它们无法扩展。

任何 MongoDB 不过滤分片键的查询,将被广播到所有分片。此外,范围查询可能会导致广播或至少导致您的查询被发送到多个分片。

所以这里有一些事情需要考虑

  • 查询频率 -- 范围查询是您最常查询的吗?什么 是预期的工作量?
  • Range Logic -- 是否有任何内在的逻辑来说明你将如何去 应用范围?比方说,你会说 0-200 很小,200 - 400 是中等。您可能会在文档中添加另一个字段 并在上面切分。
  • Additional shard key candidates -- 有时还有其他字段 可以包含在您的所有或大部分查询中,它会 提供良好的分布。通过将过滤与您的范围相结合 您可以将查询限制为一个或更少的分片。
  • 中断数组 -- 您可能有多个文档 的一个数组。在这种情况下,您将有多个文档,一个用于 数组和主数据的每次出现都将重复 多个文档。此项的范围查询仍然是 问题,但您可能涉及多个分片,不一定是所有分片 (这取决于您的数据人口统计和查询模式)

这归结为您的数据和查询的性质。您提供的示例文档是非常匿名的,因此很难知道在您的域中什么是好的候选分片键。

最后一条建议是,如果您打算经常更新文档以向数组中添加更多条目,请注意您的 insert/update 查询模式。 Growing documents present scaling problems for MongoDB. See this article on this topic.