【问题标题】:Aggregate function with JavaScript query API in Azure Cosmos DBAzure Cosmos DB 中使用 JavaScript 查询 API 的聚合函数
【发布时间】:2019-11-19 08:12:52
【问题描述】:

我正在使用 CosmosDB 存储过程和用户​​定义函数。

我必须编写一个存储过程来返回集合的四个字段中的最大值。

我在 Sql 中写:

    SQL MAX(A) AS MASSIMOA, MAX(B) AS MASSIMOB, .... FROM COLLECTION

我不知道如何使用 javascript 将其写入存储过程。 谁能帮我? 西蒙娜

样本数据:

    {
        "messageUID": "EBBBrain-10608941722019-05-31T16:58:13+02:00",
        "deviceId": "EBBBrain-1060894172",
        "dateTimeDevice": "2019-05-31T14:58:13",
        "messageId": 38,
        "release": 104,
        "VIn": 23342,
        "VOut": 20513,
        "AIn": 53,
        "AOut": 40,
        "CosPhi": 42,
        "W": 53,
        "Var": 112,
        "VA": 124,
        "WhCnt": 361587,
        "VarhCnt": 749631,
        "TimeSlot": 0,
        "MeterTS": "2019-05-31 16:58:14",
        "Sampling": 60,
        "Wh": 3423,
        "Varh": 7105,
        "WSaved": 0,
        "EventProcessedUtcTime": "2019-05-31T14:58:15.3238226Z",
        "PartitionId": 1,
        "EventEnqueuedUtcTime": "2019-05-31T14:58:15.285Z",
        "IoTHub": {
            "MessageId": null,
            "CorrelationId": null,
            "ConnectionDeviceId": "Device",
            "ConnectionDeviceGenerationId": "636909297614425839",
            "EnqueuedTime": "2019-05-31T14:58:15.292Z",
            "StreamId": null
        },
        "id": "EBBBrain-1060894172",
        "_rid": "dEkOAONukREBAAAAAAAAAA==",
        "_self": "dbs/dEkOAA==/colls/dEkOAONukRE=/docs/dEkOAONukREBAAAAAAAAAA==/",
        "_etag": "\"2400a1a2-0000-0c00-0000-5cf1415c0000\"",
        "_attachments": "attachments/",
        "_ts": 1559314780
    }

和基于样本的sql语句是:

    SELECT max(r.VIn) as maxNum FROM root r

【问题讨论】:

标签: azure-cosmosdb java-stored-procedures


【解决方案1】:

Cosmos db 支持原生 aggregate function 如下:

所以,你可以在普通 sql 中使用MAX

'SELECT max(r.num) as maxNum FROM root r'

在存储过程中,没有更多的区别。

// SAMPLE STORED PROCEDURE
function sample() {
    var collection = getContext().getCollection();

    var isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        'SELECT max(r.num) as maxNum FROM root r',
    function (err, feed, options) {
        if (err) throw err;

        if (!feed || !feed.length) {
            var response = getContext().getResponse();
            response.setBody('no docs found');
        }
        else {
            var response = getContext().getResponse();
            response.setBody(feed);
        }
    });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

输出:


更新答案:

问题是由数据大小引起的。如果您未在查询 sql 中设置任何过滤器,cosmos db 中的聚合函数将跨越所有数据。这是一个巨大的工作量,不能直接通过存储过程完成。存储过程有执行限制,请参考link

所以,我的建议是使用延续令牌来完成分页。您可以在代码中设置maxItemCount 参数,如下所示:

client.QueryDocuments(collection_link, query, {'maxItemCount':100})

然后使用延续令牌来获取单页的最大数量。最后,比较这些数字以获得最大值。关于continuation token的使用,可以参考这个帖子:Document DB 5 secs stored procedure execution limit

【讨论】:

  • 我在我的环境中尝试您的代码,将我的字段放在 select 子句中。我有个问题 。结果是 [ {} ] 有什么问题?谢谢。西蒙娜
  • @SimoneSpagna 没关系,你的数据是什么,我们的存储过程代码有什么区别?
  • 查看我的回复。非常感谢。西蒙娜
  • @SimoneSpagna 很抱歉错过了您的更新回复。因此,即使您执行 select * from c 也会得到空结果。也许您应该先直接在azure门户中执行sql。您是否跳入了不匹配的集合或该集合是否确实有项目?请再次查看,等待您的回复!
  • 如果 j 执行 select * from c from c from azure protal 我将获得集合的前 100 条记录 ....................
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多