对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

细化CollectionShardKey(数据库命令)

refineCollectionShardKey

通过添加新字段作为现有键的后缀来修改集合的分片键。 优化collection的分片键可以解决由于关联基数不足而导致现有键产生巨型(即不可分割)数据块的情况。

注意

数据分布

As part of refining the shard key, the refineCollectionShardKey command updates the chunk ranges and zone ranges to incorporate the new fields without modifying the range values of the existing key fields. That is, the refinement of the shard key does not immediately affect the distribution of chunks across shards or zones. Any future chunk splits or migration occur as part of the routine sharding operations.

此命令可用于以下环境中托管的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

重要

M 个10 + 集群不支持此命令。 有关更多信息,请参阅不支持的命令。

注意

To use the refineCollectionShardKey command, the sharded cluster must have feature compatibility version (fcv) of 4.4.

该命令具有以下语法:

db.adminCommand(
{
refineCollectionShardKey: "<database>.<collection>",
key: { <existing key specification>, <suffix1>: <1|"hashed">, ... }
}
)

该命令接受以下字段:

字段
类型
说明

字符串

sharded collection的命名空间,采用"<database>.<collection>"形式。

文档

指定要用作集合的新分片键的一个或多个字段的文档。

{ <existing key specification>, <suffix1>: <1|"hashed">, ... }

对于后缀字段,将字段值设置为:

提示

分片键

使用访问控制运行时,用户必须对refineCollectionShardKey 数据库和/或集合 具有 操作权限才能运行命令。也就是说,用户必须具有授予以下 权限 的 角色

{ resource: { db: <database>, collection: <collection> }, actions: [ "refineCollectionShardKey" ] }

内置 clusterManager 角色提供了相应的特权。

  • 索引存在性

    An index that supports the command's specified key must exist prior to running the command.

    支持索引是以新的分片键规范开头的索引;即索引前缀与新的分片键规范匹配。 也就是说,要将分片键从{ x: 1 }更改为{ x: 1, y: 1 } ,必须存在以{ x: 1, y: 1 }开头的索引;例如

    • { x: 1, y: 1 }

    • { x: 1, y: 1, a: 1, b: 1}

    注意

    • 支持索引不能是部分索引。

    • 支持索引不能是稀疏索引。

    • 如果集合使用非simple排序规则,则支持索引必须指定{ locale: "simple" }排序规则。

  • 唯一索引

    如果当前分片索引具有唯一性约束,则新的分片键索引也必须具有唯一性约束。

    After creating the unique index to support the new shard key, drop the old shard key index before running refineCollectionShardKey.

    此外,如果当前分片索引具有唯一性约束,则新分片键不能为其任何字段指定"hashed"

    另请参阅Sharded collection 和 唯一索引

  • 索引排序规则
    如果分片collection具有非simple默认排序规则,则索引必须包含具有{ locale : "simple" }的排序规则文档。 对于字段支持分片键模式的索引,必须至少有一个索引采用简易排序规则。

警告

请勿修改任何当前分片键字段的范围或哈希类型。这会导致数据不一致。例如,请勿将分片密钥从 { customer_id: 1 } 修改为 { customer_id: "hashed", order_id: 1 }

要在test数据库中设置示例,请执行以下操作:

  1. 使用以下shardCollection 操作对orders test数据库中的collection进行分片。该操作使用customer_id字段作为初始分片键:

    db.adminCommand( { shardCollection: "test.orders", key: { customer_id: 1 } } )

要将分片键修改为customer_id字段和order_id字段{ customer_id: 1, order_id: 1 }

  1. Create the index 以支持新的分片键(如果索引尚不存在)。

    db.getSiblingDB("test").orders.createIndex( { customer_id: 1, order_id: 1 } )
  2. Run refineCollectionShardKey command to add the order_id field as a suffix:

    db.adminCommand( {
    refineCollectionShardKey: "test.orders",
    key: { customer_id: 1, order_id: 1 }
    } )

成功完成该命令后,集合的分片键已更改为{ customer_id: 1, order_id: 1 } 。 要进行验证,您可以运行sh.status()

提示

优化分片键后,可能并非集合中的所有文档都具有后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段

在细化分片键之前,请确保集合中的所有或大多数文档都具有后缀字段(如果可能),以避免后期再填充字段。

要在test数据库中设置示例,请执行以下操作:

  1. test数据库中创建caféscollection,指定法语fr作为默认排序规则。

    db.getSiblingDB("test").createCollection( "cafés", { collation: { locale: "fr" } } );
  2. 使用customer_id字段作为初始分片键对collection进行分片。由于该collection具有默认的fr排序规则而不是simple排序规则,因此shardCollection命令必须包含collation: { locale: "simple" }选项:

    db.adminCommand( {
    shardCollection: "test.cafés",
    key: { customer_id: 1 },
    collation: { locale: "simple" }
    } )

要将分片键修改为customer_id字段和order_id字段{ customer_id: 1, order_id: 1 }

  1. Create the index以支持新的分片键(如果该索引尚不存在)。 由于collection使用非简单排序规则,因此索引必须包含collation: { locale: "simple" }选项。

    db.getSiblingDB("test").cafés.createIndex(
    { customer_id: 1, order_id: 1 },
    { collation: { locale: "simple" } }
    )
  2. Run refineCollectionShardKey command to add the order_id field as a suffix:

    db.adminCommand( {
    refineCollectionShardKey: "test.cafés",
    key: { customer_id: 1, order_id: 1 }
    } )

成功完成该命令后,集合的分片键已更改为{ customer_id: 1, order_id: 1 } 。 要进行验证,您可以运行sh.status()

提示

优化分片键后,可能并非集合中的所有文档都具有后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段

在细化分片键之前,请确保集合中的所有或大多数文档都具有后缀字段(如果可能),以避免后期再填充字段。

提示

分片键