mongo 哪些指令条件需要包含分片键

一、mongo分片原理

          在MongoDB中,数据根据一个称为分片键(Shared Key) 的字段进行分片。根据指定字段按照指定分片方式(哈希分片、范围分片)将数据拆分到mongo集群里的不同服务器中

        分片键的选择非常关键,它应该能够确保数据均匀分布,避免热点问题。

        分片键通常是在文档中的一个字段,MongoDB根据这个字段的值来决定将文档存储在哪个分片上

二、分片作用

       1、MongoDB分片的主要优势在于它允许数据库在数据量增加时水平扩展

           通过增加更多的分片来处理更多的负责。通过增加更多的分片来处理更多的负载。分片键的选择和分片集群的规划是关键的设计决策,因为它们直接影响了系统的性能和可扩展性

      2、提高查询效率

           当我们在使用条件查询时,如果查询条件中包含了分片键,MongoDB就可以利用分片键来进行数据定位,确定数据存储在哪个分片上,从而只在特定的分片上进行查询, 而不是在整个集群中搜搜,可以大大减少查询的范围,提高查询效率

三、是不是所有的MongoDB 指令条件都需要包含分片键

      最好在MongoDB指令(如查找、更新、删除)操作时,条件都包含分片键,这样可以提高查询效率。但在实际业务中,常常不同的db操作指令,可能会有自己的索引,而索引不一定都能命中分片键。 这种情况下就不能实现所有的条件都包含分片键了。

     举个例子:

        现在有一个umsg库,索引、分片键声明如下

"umsg": {
        "indexes" : [
            {
                "index": [
                    ["_id", 1]    //索引1
                ],
                "options": {
                }
            },
            {
                "index": [
                    ["avatarID", 1]   //索引2
                ],
                "options": {
                }
            }
        ],
        "shard_key": {"_id": "hashed"}  // _id 分片键,分片方式:哈希分片
    },

     1)update指令更新数据,指令操作失败

更新指令:
db.getCollection('umsg').update({id:1}, {$set:{a:1}})



更新报错:
A single update on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Update request: { q: { id: 1.0 }, u: { $set: { a: 1.0 } }, multi: false, upsert: false }, shard key pattern: { _id: "hashed" }

   2)deleteOne指令删除数据,指令操作失败

删除指令:
db.getCollection('umsg').deleteOne({id:1})



删除结果:
Failed to execute script.

Error:
WriteError({
	"index" : 0,
	"code" : 61,
	"errmsg" : "A single delete on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Delete request: { q: { id: 1.0 }, limit: 1 }, shard key pattern: { _id: \"hashed\" }",
	"op" : {
		"q" : {
			"id" : 1
		},
		"limit" : 1
	}
}) :
WriteError({
	"index" : 0,
	"code" : 61,
	"errmsg" : "A single delete on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Delete request: { q: { id: 1.0 }, limit: 1 }, shard key pattern: { _id: \"hashed\" }",
	"op" : {
		"q" : {
			"id" : 1
		},
		"limit" : 1
	}
})
WriteError@src/mongo/shell/bulk_api.js:458:48
mergeBatchResults@src/mongo/shell/bulk_api.js:855:49
executeBatch@src/mongo/shell/bulk_api.js:919:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1163:21
DBCollection.prototype.deleteOne@src/mongo/shell/crud_api.js:375:17
@(shell):1:1

3)   findAndModify、findOneAndUpdate、findOneAndDelete 指令 ,指令操作失败

查找并更新指令
db.getCollection('umsg').findAndModify({id:1}, {$set:{a:1}})
查找单条数据并更新指令
db.getCollection('umsg').findOneAndUpdate({id:1}, {$set:{a:1}})
茶轴单条数据并删除指令
db.getCollection('umsg').findOneAndDelete({id:1}, {$set:{a:1}})


操作结果:

Failed to execute script.

Error:
Uncaught exception: Error: findAndModifyFailed failed: {
	"ok" : 0,
	"errmsg" : "Query for sharded findAndModify must contain the shard key",
	"code" : 61,
	"codeName" : "ShardKeyNotFound",
	"operationTime" : Timestamp(1710298791, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1710298791, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DBCollection.prototype.findAndModify@src/mongo/shell/collection.js:725:15
@(shell):1:1

4)findOne和find查询指令,正常

db.getCollection('umsg').find({id:1})

db.getCollection('umsg').findOne({id:1})

结论:

      查找条件不一定要包含分片键(会去不同的分片上查询,效率低),修改到文档数据的指令操作条件都要包含分片键。

你可能感兴趣的:(mongo,数据库,mongodb)