Hashed Indexes散列索引

On this page本页内容

Hashed indexes maintain entries with hashes of the values of the indexed field.散列索引使用索引字段值的散列来维护条目。

Hashed indexes support sharding using hashed shard keys. 哈希索引支持使用哈希切分键进行切分Hashed based sharding uses a hashed index of a field as the shard key to partition data across your sharded cluster.基于散列的分片使用字段的散列索引作为分片键,在分片集群中对数据进行分区。

Using a hashed shard key to shard a collection results in a more random distribution of data. 使用散列切分键对集合进行切分会导致数据分布更加随机。See Hashed Sharding for more details.有关更多详细信息,请参阅散列切分

Hashing Function散列函数

Hashed indexes use a hashing function to compute the hash of the value of the index field. 散列索引使用散列函数计算索引字段值的散列。[1] The hashing function collapses embedded documents and computes the hash for the entire value but does not support multi-key (i.e. arrays) indexes. 哈希函数折叠嵌入的文档并计算整个值的哈希,但不支持多键(即数组)索引。Specifically, creating a hashed index on a field that contains an array or attempting to insert an array into a hashed indexed field returns an error.具体来说,在包含数组的字段上创建哈希索引或尝试将数组插入哈希索引字段会返回错误。

Tip

MongoDB automatically computes the hashes when resolving queries using hashed indexes. 当使用散列索引解析查询时,MongoDB会自动计算散列。Applications do not need to compute hashes.应用程序不需要计算散列。

[1]Starting in version 4.0, the mongo shell provides the method convertShardKeyToHashed(). 从4.0版开始,mongo shell提供了convertShardKeyToHashed()方法。This method uses the same hashing function as the hashed index and can be used to see what the hashed value would be for a key.此方法使用与散列索引相同的散列函数,并可用于查看键的散列值。

Create a Hashed Index创建散列索引

To create a hashed index, specify hashed as the value of the index key, as in the following example:要创建哈希索引,请指定hashed作为索引键的值,如下例所示:

db.collection.createIndex( { _id: "hashed" } )

Create a Compound Hashed Index创建复合哈希索引

New in version 4.4.版本4.4中的新功能。

Starting with MongoDB 4.4, MongoDB supports creating compound indexes that include a single hashed field. 从MongoDB 4.4开始,MongoDB支持创建包含单个散列字段的复合索引。To create a compound hashed index, specify hashed as the value of any single index key when creating the index:要创建复合哈希索引,请在创建索引时将哈希指定为任何单个索引键的值:

db.collection.createIndex( { "fieldA" : 1, "fieldB" : "hashed", "fieldC" : -1 } )

Compound hashed indexes require featureCompatibilityVersion set to 4.4.复合哈希索引要求featureCompatibilityVersion设置为4.4

Considerations考虑事项

Embedded Documents嵌入文档

The hashing function collapses embedded documents and computes the hash for the entire value, but does not support multi-key (i.e. arrays) indexes. 哈希函数折叠嵌入的文档并计算整个值的哈希,但不支持多键(即数组)索引。Specifically, creating a hashed index on a field that contains an array or attempting to insert an array to a hashed indexed field returns an error.具体来说,在包含数组的字段上创建散列索引或尝试将数组插入散列索引字段会返回错误。

Unique Constraint唯一约束

MongoDB does not support specifying a unique constraint on a hashed index. MongoDB不支持在hashed索引上指定唯一约束。You can instead create an additional non-hashed index with the unique constraint on that field. 您可以在该字段上创建一个具有唯一约束的附加非散列索引。MongoDB can use that non-hashed index for enforcing uniqueness on the field.MongoDB可以使用该非散列索引来强制字段的唯一性。

253 Limit

Warning警告

MongoDB hashed indexes truncate floating point numbers to 64-bit integers before hashing. MongoDBhashed索引在散列之前将浮点数截断为64位整数。For example, a hashed index would store the same value for a field that held a value of 2.3, 2.2, and 2.9. 例如,hashed索引将为一个值为2.32.22.9的字段存储相同的值。To prevent collisions, do not use a hashed index for floating point numbers that cannot be reliably converted to 64-bit integers (and then back to floating point). 为了防止冲突,不要对无法可靠转换为64位整数(然后再转换回浮点)的浮点数使用hashed索引。MongoDB hashed indexes do not support floating point values larger than 253.MongoDBhashed索引不支持大于253的浮点值。

To see what the hashed value would be for a key, see convertShardKeyToHashed().要查看键的哈希值,请参阅convertShardKeyToHashed()

PowerPC and 263

For hashed indexes, MongoDB 4.2 ensures that the hashed value for the floating point value 263 on PowerPC is consistent with other platforms.对于散列索引,MongoDB 4.2确保PowerPC上浮点值263的散列值与其他平台一致。

Although hashed indexes on a field that may contain floating point values greater than 253 is an unsupported configuration, clients may still insert documents where the indexed field has the value 263.虽然对可能包含大于253的浮点值的字段进行哈希索引是不受支持的配置,但客户端仍可以在索引字段的值为263的地方插入文档。

To list all hashed indexes for all collections in your deployment, you can use the following operation in the mongo shell:要列出部署中所有集合的所有hashed索引,可以在mongo shell中使用以下操作:

db.adminCommand("listDatabases").databases.forEach(function(d){
   let mdb = db.getSiblingDB(d.name);
   mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){
      let currentCollection = mdb.getCollection(c.name);
      currentCollection.getIndexes().forEach(function(idx){
        let idxValues = Object.values(Object.assign({}, idx.key));

        if (idxValues.includes("hashed")) {
          print("Hashed index: " + idx.name + " on " + d.name + "." + c.name);
          printjson(idx);
        };
      });
   });
});

To check if the indexed field contains the value 263, run the following operation for the collection and the indexed field:要检查索引字段是否包含值263,请对集合和索引字段运行以下操作:

  • If the indexed field type is a scalar and never a document:如果索引字段类型是标量,而不是文档:

    // substitute the actual collection name for <collection>
    // substitute the actual indexed field name for <indexfield>
    
    db.<collection>.find( { <indexfield>: Math.pow(2,63) } );
  • If the indexed field type is a document (or a scalar), you can run:如果索引字段类型是文档(或标量),则可以运行:

    // substitute the actual collection name for <collection>
    // substitute the actual indexed field name for <indexfield>
    
    db.<collection>.find({
        $where: function() {
            function findVal(obj, val) {
                if (obj === val)
                    return true;
    
                for (const child in obj) {
                    if (findVal(obj[child], val)) {
                        return true;
                    }
                }
                return false;
            }
            return findVal(this.<indexfield>, Math.pow(2, 63));
        }
    })