通过.NET Core创建调用Azure Cosmos DB MongoDB存储过程报错求解
正确实现Azure Cosmos DB for MongoDB API存储过程的创建与调用
失败原因说明
- Azure Cosmos DB for MongoDB API 不支持原生MongoDB的
eval命令,所以你两种基于eval的调用方式都会抛出不支持异常 - 你当前的创建代码存在参数不匹配问题:插入
System.js集合时指定的_id为mathSum,需要和js文件内定义的函数名完全一致,否则会出现函数找不到的错误
正确的存储过程创建代码
首先确认js文件(以sum.js为例)内容,函数名需要和后续插入的_id值保持一致:
function addNumbers(num1, num2) { return num1 + num2; }
C#侧创建存储过程代码:
// 需提前引入命名空间:MongoDB.Driver、MongoDB.Bson var sysJs = azureDatabase.GetCollection<BsonDocument>("System.js"); var code = File.ReadAllText(@"sum.js的本地存储路径"); var codeDocument = new BsonDocument { // _id必须和js文件内的函数名完全一致 {"_id", "addNumbers"}, {"value", new BsonJavaScript(code)} }; sysJs.InsertOne(codeDocument);
正确的调用方式
不能使用eval,需通过聚合管道的$function操作符调用已存储的服务端函数:
// 构造聚合管道 var pipeline = new BsonDocument[] { // 取1条数据作为执行载体,无业务影响 new BsonDocument("$limit", 1), new BsonDocument("$project", new BsonDocument { { "result", new BsonDocument("$function", new BsonDocument { // 对应已存储的函数名 { "body", "addNumbers" }, // 传入函数的参数 { "args", new BsonArray { 2, 3 } }, { "lang", "js" } }) } }) }; // 此处集合名替换为你数据库中任意已存在的集合名称即可 var callResult = azureDatabase.GetCollection<BsonDocument>("现有集合名") .Aggregate<BsonDocument>(pipeline) .FirstOrDefault()["result"].AsInt32;
上述代码执行后callResult的值就是2+3的计算结果5。
注意事项
- 推荐使用2.14及以上版本的MongoDB.Driver驱动,避免出现版本兼容问题
- 服务端JS函数单次执行最长时间为5秒,仅适合轻量计算场景
- 存储的函数可以直接在查询、更新、聚合的服务端上下文内调用,无需每次都传递函数体
内容的提问来源于stack exchange,提问作者Diva
相关产品推荐
相关产品推荐

