sho*_*ver 6 recursion stored-procedures azure-cosmosdb
有没有办法递归调用存储过程(甚至UDF,如果这将工作)对DocumentDB文档?
我们有一个看起来像这样的文档:
{
"docID" : "my_id",
"owner" : "fred",
"items" : [
{
"itemID" : "1",
"type" : "item",
"value" : 3
},
{
"itemID" : "2",
"type" : "group",
"items" : [
{
"itemID" : "2.1",
"type" : "group",
"items" : [
{
"itemID" : "2.1.1",
"type" : "item",
"value" : 2
},
{
"itemID" : "2.1.2",
"type" : "item",
"value" : 4
}
]
},
{
"itemID" : "2.2",
"type" : "item",
"value" : 1
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
任何时候我们都有"items",该"items"数组可以包含混合的"type" : "item"和"type" : "group"."type" : "item"具有"value"需要求和的简单字段的条目."type" : "group"具有"items"数组的条目......等等.从理论上讲,递归水平没有限制,我承认这是一个问题,但在实践中,水平很少会低于4或5深.
我正在尝试编写的伪代码看起来像这样:
function sumValues(items) {
int total = 0;
forEach(item in items) {
if (item.type == "item") {
total += item.value;
} else {
total += sumValues(item.items);
}
}
return total;
}
function sumAllValues() {
var ctx = getContext();
var coll = ctx.getCollection();
var response = ctx.getResponse();
// query for docs by owner
var filterQuery = 'SELECT * FROM Docs d where d.owner = \\\"fred\\\"';
var done = coll.queryDocuments(coll.getSelfLink(), filterQuery, {},
function (err, docs, options) {
if (err) throw new Error ('Error' + err.message);
var total = 0;
docs.forEach(function(doc) {
total += sumTotals(doc.items);
});
response.setBody('Total: ' + total);
});
}
Run Code Online (Sandbox Code Playgroud)
这甚至可能吗?DocumentDB是否支持从另一个sproc调用sproc?一个sproc可以自己调用吗?
我在网上找了几个DocumentDB存储过程的引用,包括这个和这个和这个和这个加上其他页面的主机.
如果可能,我想我可能不得不以某种方式查询集合以获取我想调用的sproc,然后以某种方式引用sproc,而不是sumTotals()像使用独立语言那样直接调用.
我们刚刚开始研究使用DocumentDB编程,所以我们还不能完全确定我们可以用它做什么.感谢您提供任何帮助或建议.
我想你在这里走在正确的轨道上.
无法从存储过程中执行存储过程.
但是,您可以在存储过程中定义JS函数,可以在该存储过程中引用,调用和重用它们.
在这种情况下,只需sumValues()在父sumAllValues()存储过程中定义您的函数(就像swapItems()您提到的示例一样).
function sumAllValues() {
var ctx = getContext();
var coll = ctx.getCollection();
var response = ctx.getResponse();
// query for docs by owner
var filterQuery = 'SELECT * FROM Docs d where d.owner = \\\"fred\\\"';
var done = coll.queryDocuments(coll.getSelfLink(), filterQuery, {},
function (err, docs, options) {
if (err) throw new Error ('Error' + err.message);
var total = 0;
docs.forEach(function(doc) {
total += sumValues(doc.items);
});
response.setBody('Total: ' + total);
});
function sumValues(items) {
int total = 0;
items.forEach(function(item) {
if (item.type == "item") {
total += item.value;
} else {
total += sumValues(item.items);
}
});
return total;
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以为要在多个存储过程和查询中共享和重用的逻辑定义UDF.