SELECT VALUE COUNT(1) FROM (SELECT DISTINCT c.UserId FROM root c) AS t 不工作
SELECT VALUE COUNT(1) FROM (SELECT DISTINCT c.UserId FROM root c) AS t not working
在 Cosmos DB 存储过程中,我使用内联 sql 查询来尝试检索特定用户 ID 的非重复计数。
我正在为我的帐户使用 SQL API。我在我的 Cosmos DB 帐户的查询资源管理器中有 运行 以下查询,我知道我应该得到 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。
UserId 是我的分区键,我在我的 C# 代码中传递它,当我在门户中测试它时,所以我不需要设置其他参数调用存储过程时。我通过 C# 调用此存储过程并添加任何其他参数将影响我对该代码的测试,因此我希望尽可能不引入任何参数。
您的问题是因为您没有为存储过程设置分区键。
请看官方的说法document:
还有这个:
因此,在分区集合下执行存储过程时,需要传递分区键参数。这是必要的! (这个案例也说明了这一点:Documentdb stored proc cross partition query)
回到你的问题,你从来没有传递任何分区键,等于你为分区键传递了一个null
值或""
值,所以它不输出任何数据,因为你没有任何userId 等于 null 或 "".
我的建议:
您可以使用普通的 Query SDK 来执行您的 sql,并设置 enableCrossPartitionQuery: true
,这样您就可以在不设置分区键的情况下扫描整个集合。请参考这个小样本:
所以我找到了 returns 我需要的结果的解决方案。我的存储过程现在看起来像这样:
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 成本方面会更贵,但它暂时解决了我的问题。
如果有人有更有效的替代方案,请发表评论并告诉我。
在 Cosmos DB 存储过程中,我使用内联 sql 查询来尝试检索特定用户 ID 的非重复计数。
我正在为我的帐户使用 SQL API。我在我的 Cosmos DB 帐户的查询资源管理器中有 运行 以下查询,我知道我应该得到 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。
UserId 是我的分区键,我在我的 C# 代码中传递它,当我在门户中测试它时,所以我不需要设置其他参数调用存储过程时。我通过 C# 调用此存储过程并添加任何其他参数将影响我对该代码的测试,因此我希望尽可能不引入任何参数。
您的问题是因为您没有为存储过程设置分区键。
请看官方的说法document:
还有这个:
因此,在分区集合下执行存储过程时,需要传递分区键参数。这是必要的! (这个案例也说明了这一点:Documentdb stored proc cross partition query)
回到你的问题,你从来没有传递任何分区键,等于你为分区键传递了一个null
值或""
值,所以它不输出任何数据,因为你没有任何userId 等于 null 或 "".
我的建议:
您可以使用普通的 Query SDK 来执行您的 sql,并设置 enableCrossPartitionQuery: true
,这样您就可以在不设置分区键的情况下扫描整个集合。请参考这个小样本:
所以我找到了 returns 我需要的结果的解决方案。我的存储过程现在看起来像这样:
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 成本方面会更贵,但它暂时解决了我的问题。
如果有人有更有效的替代方案,请发表评论并告诉我。