DocumentDB从另一个存储过程或其本身调用存储过程 [英] DocumentDB call stored procedure from another stored procedure or itself
问题描述
是否有一种方法可以针对DocumentDB文档递归地调用存储过程(甚至可以使用UDF)?
Is there a way to recursively call stored procedures (or even UDFs if that will work) against DocumentDB documents?
我们有一个看起来像这样的文档:
We have a document that looks something like this:
{
"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
}
]
}
]
}
任何时候只要有"items"
,该"items"
数组都可以包含由"type" : "item"
和"type" : "group"
混合而成的条目. "type" : "item"
的条目具有一个简单的"value"
字段,需要对其求和. "type" : "group"
的条目具有"items"
数组...等等.从理论上讲,递归级别没有限制,我承认这是一个问题,但是在实践中,递归级别很少会低于4或5.
Any time we have "items"
, that "items"
array can contain entries that are a mix of "type" : "item"
and "type" : "group"
. Entries that are of "type" : "item"
have a simple "value"
field that needs to be summed. Entries that are of "type" : "group"
have an "items"
array... and so on. In theory, there is no limit to the level of recursion, which I acknowledge is a problem, but in practice, the levels will rarely get below 4 or 5 deep.
我要写的伪代码看起来像这样:
Pseudocode for what I'm trying to write looks something like this:
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);
});
}
这甚至有可能吗? DocumentDB是否支持从另一个存储过程调用一个存储过程? sproc可以自己调用吗?
Is this even possible? Does DocumentDB support calling a sproc from another sproc? Can a sproc call itself?
我在网上找到了一些DocumentDB存储过程参考,包括此和此和这以及其他许多页面.
I have found a few DocumentDB stored procedure references online, including this and this and this and this plus a host of other pages.
如果可能的话,我想我可能必须以某种方式查询集合以获取要调用的sproc,然后以某种方式引用该sproc,而不是像使用独立语言那样直接调用sumTotals()
.
If it's possible, I think I might have to somehow query the collection to get the sproc that I want to call, and then somehow reference the sproc, instead of just calling sumTotals()
directly as you would with a standalone language.
我们只是开始研究使用DocumentDB进行编程,因此我们还不确定是否可以使用它进行处理.感谢您的帮助或建议.
We're just starting to look at programming with DocumentDB, so we're not completely sure what we can do with it yet. Thanks for any assistance or advice.
推荐答案
我认为您在这里的路线正确.
I think you're on the right track here.
不可能从存储过程中执行存储过程.
It is not possible to execute a stored procedure from within a stored procedure.
但是,您可以在存储过程中定义JS函数,可以在该存储过程中对其进行引用,调用和重用.
However, you can define JS functions inside a stored procedure, which can be can be referenced, called, and re-used from within that stored procedure.
在这种情况下,只需在父sumAllValues()
存储过程中定义您的sumValues()
函数(就像您提到的swapItems()
示例一样).
In this case, simply define your sumValues()
function inside the parent sumAllValues()
stored procedure (just like the swapItems()
example you mentioned).
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;
}
}
您还可以为要在多个存储过程和查询之间共享和重用的逻辑定义UDF.
You can also define UDFs for logic you'd like to share and re-use across multiple stored procedures and queries.
这篇关于DocumentDB从另一个存储过程或其本身调用存储过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!