Navigation

Hashed Indexes

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.

Tip

MongoDB automatically computes the hashes when resolving queries using hashed indexes. Applications do not need to compute hashes.

[1]Starting in version 4.0, the mongo shell provides the method 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:

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

Considerations

MongoDB supports hashed indexes of any single field. The hashing function collapses embedded documents and computes the hash for the entire value, but does not support multi-key (i.e. arrays) indexes.

You may not create compound indexes that have hashed index fields or specify a unique constraint on a hashed index; however, you can create both a hashed index and an ascending/descending (i.e. non-hashed) index on the same field: MongoDB will use the scalar index for range queries.

253 Limit

Warning

MongoDB hashed indexes truncate floating point numbers to 64-bit integers before hashing. 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. 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). MongoDB hashed indexes do not support floating point values larger than 253.

To see what the hashed value would be for a key, see 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.

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.

To list all hashed indexes for all collections in your deployment, you can use the following operation in the 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 " + idx.ns);
          printjson(idx);
        };
      });
   });
});

To check if the indexed field contains the value 263, run the following operation for the collection and the indexed field:

  • 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));
        }
    })