在Cosmos DB存储过程中,我使用内联sql查询来尝试检索特定用户ID的不重复计数。
我正在为我的帐户使用SQL API。我已经在Cosmos DB帐户的Query Explorer中运行了以下查询,并且我知道应该得到10(我的集合中有10个唯一的用户ID):
SELECT VALUE COUNT(1) FROM (SELECT DISTINCT c.UserId FROM root c) AS t
但是,当我在“存储过程”门户网站中运行此命令时,我要么得到0条记录,要么得到18条记录(文档总数)。我的存储过程的代码如下:
function GetDistinctCount() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT VALUE COUNT(1) FROM (SELECT DISTINCT c.UserId FROM root c) AS t',
function(err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) {
var response = getContext().getResponse();
var body = {code: 404, body: "no docs found"}
response.setBody(JSON.stringify(body));
} else {
var response = getContext().getResponse();
var body = {code: 200, body: feed[0]}
response.setBody(JSON.stringify(body));
}
}
)
}
在查看了各种反馈论坛和文档之后,我认为没有一个像普通SQL那样简单的优雅解决方案。
用户ID是我的分区键,我在C#代码中以及在门户中对其进行测试时会通过该键,因此在调用Stored Proc时不需要设置其他参数。我正在通过C#调用此存储过程,并添加任何其他参数将对该代码的测试产生影响,因此,我尽可能不引入任何参数。
答案 0 :(得分:0)
您的问题是由于您没有为存储过程设置分区键而引起的。
请参见官方document中的声明:
这:
因此,当您在分区集合下执行存储过程时,需要传递分区键参数。这是必要的! (此案例也对此进行了解释:Documentdb stored proc cross partition query)
回到您的问题,您永远不会传递任何分区键,就等于您传递了分区键的null
值或""
值,因此它不输出任何数据,因为您没有任何userId等于null或“”。
我的建议:
您可以使用普通的Query SDK来执行您的sql,并设置enableCrossPartitionQuery: true
,以使您无需设置分区键即可扫描整个集合。请参考这个小样本:Can't get simple CosmosDB query to work via Node.js - but works fine via Azure's Query Explorer
答案 1 :(得分:0)
因此,我找到了一个返回所需结果的解决方案。我的存储过程现在看起来像这样:
function GetPaymentCount() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT DISTINCT VALUE(doc.UserId) from root doc' ,
{pageSize:-1 },
function(err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) {
var response = getContext().getResponse();
var body = {code: 404, body: "no docs found"}
response.setBody(JSON.stringify(body));
} else {
var response = getContext().getResponse();
var body = {code: 200, body: JSON.stringify(feed.length)}
response.setBody(JSON.stringify(body));
}
}
)
}
本质上,我将pageSize参数更改为-1,该参数返回了我知道会在结果中返回的所有文档。我有一种感觉,就RU / s的成本而言,这将更加昂贵,但现在可以解决我的情况。
如果有人有更有效的替代方法,请发表评论并让我知道。