MongoDB 哈希索引
Posted MongoDB
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB 哈希索引相关的知识,希望对你有一定的参考价值。
哈希索引
哈希函数
创建一个哈希索引
注意事项
哈希索引使用字段的哈希值构建索引。
MongoDB分片中也支持哈希分片键。在分片集群中,如果数据记录的某字段使用哈希索引,在分片中仅需为该字段创建哈希分片键即可。
在分片集群中对一个collection进行哈希分片会导致更多的数据随机分布 。
哈希函数
哈希索引使用一个散列函数计算索引字段的哈希值。对于是嵌套文档的字段,哈希函数将计算整个嵌套文档的哈希值。在多键索引中不能使用哈希索引。
提示:
在执行使用到哈希索引的查询时自动计算哈希值,不需要应用程序自己计算查询字段的哈希值。
从MongoDB 4.0开始,mongo
shell 提供 convertShardKeyToHashed()
函数。该函数可以用来查看一个键的哈希值。
创建哈希索引
对记录的指定字段创建哈希索引,命令如下:
db.collection.createIndex( { _id: "hashed" } )
注意事项
MongoDB支持对任何单一字段创建哈希索引,对于是嵌套文档的字段,哈希函数将计算整个嵌套文档的散列值,(例如:"a":{"b":"xxx","c":"xxx"},对于a字段创建哈希索引,哈希函数将计算整个{"b":"xxx","c":"xxx"}的散列值),但不支持在多键索引中使用哈希索引(例入:不可对属性是数组的字段创建哈希索引)。
我们不可在复合索引中使用哈希索引,也不可在哈希索引上指定唯一约束。但我们可以对同一字段创建一个哈希索引和非哈希索引(例入:升序/降序类索引):在进行范围查询时,MongoDB将自动选择升序/降序索引。
2^53^ Limit 2^53^限制
注意
MongoDB哈希索引在计算散列之前将浮点数截断为64位整数。例如:对于哈希索引属性,数据内容为
2.3
,2.2
, 和2.9
的记录对应的哈希列值是相同的。为了避免这种冲突,不建议对无法可靠转换成64位整数的浮点数属性字段创建哈希索引。MongoDB不支持对大于2^53^的浮点值使用哈希索引。
To see what the hashed value would be for a key, see convertShardKeyToHashed()
. 查看键对应的哈希值请查看convertShardKeyToHashed()
。
PowerPC and 2^63^ PowerPC 和 2^63^
PowerPC和其他处理器中,MongoDB 4.2都保证可以计算64位(8字节)双精度浮点数(-1.79E+308 ~ +1.79E+308)的哈希值。
虽然大于2^53^的浮点数属性是无法配置的,但是客户端仍然可以插入索引字段值是2^63^的文档。
查询部署的MongoDB实例中所有数据库中所有collection中的哈希索引,可以在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);
};
});
});
});
检查某个collection的索引字段数据内容是2^63^位的值,使用如下命令:
如果一个collection中的索引字段数据内容仅是数值,不存在任何文档:
// substitute the actual collection name for <collection>
// substitute the actual indexed field name for <indexfield>
db.<collection>.find( { <indexfield>: Math.pow(2,63) } );如果一个collection中的索引字段是文档(或者数值),可以执行:
// 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));
}
})
以上是关于MongoDB 哈希索引的主要内容,如果未能解决你的问题,请参考以下文章