splitVector "errmsg" : "not authorized on test to execute command

mongodb开启权限之后 

splitVector 需要的权限。

user: test_da

db: test

拥有管理元权限 都不能执行成功:

> db.system.users.find();

{ "_id" : "admin.dba", "user" : "dba", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "q5TKyUEuYqP9hgTbrCsITQ==", "storedKey" : "6g15leywZRsVMDldLi+uzTypFqs=", "serverKey" : "JWcdgRShUZMcEJk+vh71E11zoXc=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "test.test_da", "user" : "test_da", "db" : "test", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "y+IxIWUp50tA/7V6WPsEsw==", "storedKey" : "8UyEZA3HkcqbMOt0Fbrsjs/M090=", "serverKey" : "Zdbm+6bujOMJnDvILZvmEFfuxJ0=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" }, { "role" : "readWriteAnyDatabase", "db" : "admin" }, { "role" : "dbAdminAnyDatabase", "db" : "admin" } ] }

{ "_id" : "admin.test_da", "user" : "test_da", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "hc4oe75lJQynskBcK94s1g==", "storedKey" : "IV0vwdd1Yo7YqraHAHcsd0I6ypY=", "serverKey" : "8bv/5MH5EuEvlvuuMpT8//rzGeg=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" }, { "role" : "readWriteAnyDatabase", "db" : "admin" }, { "role" : "dbAdminAnyDatabase", "db" : "admin" }, { "role" : "__system", "db" : "admin" } ] }


报错信息:

> db.runCommand({splitVector: "test.nxtest_full", keyPattern: {_id: 1}, maxChunkSizeBytes: 32000000}) ;
{
        "ok" : 0,
        "errmsg" : "not authorized on test to execute command { splitVector: \"test.nxtest_full\", keyPattern: { _id: 1.0 }, maxChunkSizeBytes: 32000000.0 }",
        "code" : 13
}


解决办法:

use test
db.updateUser("test_da", {
                   roles : [
                      { role: "readWrite", db: "test" },
                      { role : "clusterManager", db : "admin"  }
                   ]

              })


只需要给 clusterManager 角色就可以了, 而不是管理员角色就拥有所有权限。






<think> 我们无法在运行时动态创建变量名(除非使用宏或元编程技巧,但这通常不推荐)。但我们可以使用map来映射errorCodeMsg到其分割结果的vector。 因此,我们可以定义一个map,其键为errorCodeMsg(即int类型),值为分割后的vector<string>。 解决方案:使用`std::map<int, std::vector<std::string>>`来存储每个错误码对应的分割结果。 步骤: 1. 定义一个存储原始字符串的map:`std::map<int, std::string> m_errorCode`,用于保存原始错误码字符串。 2. 定义另一个map来存储分割结果:`std::map<int, std::vector<std::string>> m_errorCodeSplit`。 3. 当需要分割某个错误码字符串时,使用split函数分割,并将结果存入m_errorCodeSplit中对应的键(即errorCodeMsg)下。 代码示例: </think> # 动态命名存储分割结果的解决方案 在 C++ 中,变量名是在编译时确定的,无法在运行时动态创建变量名。但我们可以通过以下两种方法实现您的需求:将分割结果存储在与 `errorCodeMsg` 相关联的容器中。 ## 解决方案 1: 使用 `std::map` 映射错误码到分割结果 这是最直接且推荐的方法,使用 `std::map` 将整数错误码映射到分割结果向量: ```cpp #include <iostream> #include <map> #include <vector> #include <string> #include <sstream> // 字符串分割函数 std::vector<std::string> split(const std::string& str, char delimiter) { std::vector<std::string> tokens; std::istringstream tokenStream(str); std::string token; while (std::getline(tokenStream, token, delimiter)) { tokens.push_back(token); } return tokens; } int main() { // 用于存储原始错误码字符串的映射 std::map<int, std::string> m_errorCode; m_errorCode.insert({1000, "ERR-FILE-NOT-FOUND"}); m_errorCode.insert({2000, "AUTH-INVALID-CREDENTIALS"}); // 用于存储分割结果的映射 std::map<int, std::vector<std::string>> errorCodeSplitResults; // 遍历所有错误码进行分割 for (const auto& [errorCode, errorStr] : m_errorCode) { // ERROR: 这里的分割结果直接与错误码关联 errorCodeSplitResults[errorCode] = split(errorStr, '-'); } // 访问特定错误码的分割结果 int targetErrorCode = 2000; const auto& splitVector = errorCodeSplitResults[targetErrorCode]; std::cout << "错误码 " << targetErrorCode << " 的分割结果:\n"; for (const auto& part : splitVector) { std::cout << " - " << part << "\n"; } // 输出: // 错误码 2000 的分割结果: // - AUTH // - INVALID // - CREDENTIALS return 0; } ``` ## 解决方案 2: 使用结构体存储命名结果 这种方法通过结构体为每组分割结果提供有意义的名称: ```cpp #include <iostream> #include <vector> #include <string> #include <map> #include <sstream> // 结构体存储命名分割结果 struct ErrorCodeComponents { std::string prefix; std::string category; std::string detail; }; // 分割并解析错误码 ErrorCodeComponents parseErrorCode(const std::string& errorStr) { std::istringstream tokenStream(errorStr); std::string token; std::vector<std::string> tokens; while (std::getline(tokenStream, token, '-')) { tokens.push_back(token); } // 创建命名结果 ErrorCodeComponents comp; if (tokens.size() > 0) comp.prefix = tokens[0]; if (tokens.size() > 1) comp.category = tokens[1]; if (tokens.size() > 2) comp.detail = tokens[2]; return comp; } int main() { std::map<int, std::string> m_errorCode; m_errorCode[1000] = "ERR-FILE-NOT-FOUND"; m_errorCode[2000] = "AUTH-INVALID-CREDENTIALS"; // 存储命名分割结果 std::map<int, ErrorCodeComponents> namedSplitResults; for (const auto& [code, str] : m_errorCode) { namedSplitResults[code] = parseErrorCode(str); } // 访问特定错误码的命名结果 int targetCode = 1000; const auto& comp = namedSplitResults[targetCode]; std::cout << "错误码 " << targetCode << " 的解析结果:\n"; std::cout << "前缀: " << comp.prefix << "\n"; std::cout << "类别: " << comp.category << "\n"; std::cout << "详情: " << comp.detail << "\n"; // 输出: // 错误码 1000 的解析结果: // 前缀: ERR // 类别: FILE // 详情: NOT return 0; } ``` ## 高级方案:运行时动态创建变量名(不推荐) 虽然不推荐,但可以通过宏或预处理器在编译时创建基于错误码的变量名: ```cpp #include <iostream> #include <vector> #include <string> #include <sstream> // 定义宏创建命名变量 #define CREATE_SPLIT_VAR(errorCode) \ std::vector<std::string> split_result_##errorCode // 分割函数 std::vector<std::string> split(const std::string& str, char delimiter) { std::vector<std::string> tokens; std::istringstream tokenStream(str); std::string token; while (std::getline(tokenStream, token, delimiter)) tokens.push_back(token); return tokens; } int main() { int errorCodeMsg = 3000; std::string errorStr = "NETWORK-CONNECTION-TIMEOUT"; // 动态创建变量名 CREATE_SPLIT_VAR(3000) = split(errorStr, '-'); // 访问变量 std::cout << "分割结果:\n"; for (const auto& part : split_result_3000) { std::cout << " - " << part << "\n"; } // 输出: // 分割结果: // - NETWORK // - CONNECTION // - TIMEOUT return 0; } ``` ### 注意事项: 1. **宏的局限性**: - 变量名在编译时创建 - 错误码必须是字面量常量(不能是变量) - 只能在宏调用的作用域内访问 2. **推荐方案**: - 对于大多数情况,使用 `std::map` 映射是最佳实践 - 结构体方法提供了更好的语义表达 - 动态命名变量违反了良好的编程实践 ## 最佳实践建议 1. **错误处理**: ```cpp // 检查分割结果是否有效 if (errorCodeSplitResults.find(targetErrorCode) == errorCodeSplitResults.end()) { throw std::runtime_error("错误码未找到: " + std::to_string(targetErrorCode)); } ``` 2. **使用智能指针管理资源**: ```cpp std::map<int, std::shared_ptr<std::vector<std::string>>> splitResultsPtr; splitResultsPtr[1000] = std::make_shared<std::vector<std::string>>(split("ERR-FILE-NOT-FOUND", '-')); ``` 3. **统一访问接口**: ```cpp const std::vector<std::string>& getSplitResult(int errorCode) { static std::map<int, std::vector<std::string>> cache; if (cache.find(errorCode) == cache.end()) { cache[errorCode] = split(m_errorCode[errorCode], '-'); } return cache[errorCode]; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值