在 Azure Cosmos DB 中使用 JavaScript 查询 API 的聚合函数

Aggregate function with JavaScript query API in Azure Cosmos DB

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

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

在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

Cosmos db 支持本机 aggregate function,如下所示:

因此,您可以正常使用 MAX sql。

'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 获取最大单页数。最后,比较这些数字以获得最大值。关于continuation token的使用,可以参考这个帖子: