为每个“组”选择最新的文档

问题描述

我正在使用Azure Cosmos DB sql API尝试实现以下目标;

我们将设备数据存储在一个集合中,并且希望有效地检索每个设备序列号的 最新事件数据 ,而不必对每个设备分别进行N次查询。 / p>

SELECT * 
FROM c
WHERE c.serial IN ('V55555555','synap-aim-g1') ORDER BY c.EventEnqueuedUtcTime DESC

我假设我需要使用分组依据-https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-group-by

任何帮助将不胜感激

数据的大致示例:

[
    {
        "temperature": 25.22063251827873,"humidity": 71.54208429695204,"serial": "V55555555","testid": 1,"location": {
            "type": "Point","coordinates": [
                30.843687,-29.789895
            ]
        },"EventProcessedUtcTime": "2020-09-07T12:04:34.5861918Z","PartitionId": 0,"EventEnqueuedUtcTime": "2020-09-07T12:04:34.4700000Z","IoTHub": {
            "MessageId": null,"CorrelationId": null,"Connectiondeviceid": "V55555555","ConnectionDeviceGenerationId": "637323979596346475","EnqueuedTime": "2020-09-07T12:04:34.0000000"
        },"Name": "admin","id": "6dac491e-1f28-450d-bf97-3a15a0efaad8","_rid": "i2UhAI7ofAo3AQAAAAAAAA==","_self": "dbs/i2UhAA==/colls/i2UhAI7ofAo=/docs/i2UhAI7ofAo3AQAAAAAAAA==/","_etag": "\"430131c1-0000-0100-0000-5f5621d80000\"","_attachments": "attachments/","_ts": 1599480280
    }
]

更新: 因此,执行以下操作将返回正确的数据,但可悲的是,您只能返回group by或聚合函数中的数据(即不能选择*)

SELECT c.serial,MAX(c.EventProcessedUtcTime)
FROM c
WHERE c.serial IN ('V55555555','synap-aim-g1') 
GROUP BY c.serial

[
    {
        "serial": "synap-aim-g1","$1": "2020-09-09T06:29:42.6812629Z"
    },{
        "serial": "V55555555","$1": "2020-09-07T12:04:34.5861918Z"
    }
]

解决方法

感谢@ AnuragSharma-MSFT的帮助:

我们很高兴您以这种方式解决了该问题,感谢您共享更新:

因此,执行以下操作会返回正确的数据,但遗憾的是,您只能返回组内或聚合函数内的数据(即不能选择*)

SELECT c.serial,MAX(c.EventProcessedUtcTime)
FROM c
WHERE c.serial IN ('V55555555','synap-aim-g1') 
GROUP BY c.serial

[
    {
        "serial": "synap-aim-g1","$1": "2020-09-09T06:29:42.6812629Z"
    },{
        "serial": "V55555555","$1": "2020-09-07T12:04:34.5861918Z"
    }
]
,

如果问题实际上是针对这种特定查询场景的有效方法,那么在查询语言本身无法提供有效解决方案的情况下,我们可以考虑使用非规范化。 partitioning and modeling上的本指南中有一个有关获取Feed中最新项目的相关章节。

我们只需要获取100条最新帖子,而无需 在整个数据集中分页。

因此,为了优化最后一个请求,我们引入了第三个容器 我们的设计完全致力于满足这一要求。我们反规范化 我们发布到该新供稿容器的信息。

按照这种方法,您可以创建一个专用于“最新”查询的“ Feed”或“ LatestEvent”容器,该容器使用设备序列号为id并具有单个分区键,以确保存在每个设备只有一个(最新的)事件项,并且可以通过设备序列号获取该事件项,或使用简单的查询以最低的成本列出该事件项:

SELECT *
FROM c
WHERE c.serial IN ('V55555555','synap-aim-g1')

更改提要可用于upsert最新事件,以便在主事件中创建最新事件时在“ LatestEvent”容器中创建/覆盖最新事件。