Cosmos DB 相当于此 SQL

CosmoDB equivalent of this SQL

什么是好的 cosmdb sql 相当于这个?我有几乎相同的 sql 在 postgres 中处理虚拟 table,但似乎无法在 cosmdb 上复制它。

SELECT c.device_id FROM c
    WHERE (c.timestamp, c.device_id)
        IN (
            SELECT c.device_id, MAX(c.timestamp) FROM c WHERE c.device_id in ('00137A100000D2DB', '00137A100000D299') GROUP BY c.device_id
        )

导致错误:

 Gateway Failed to Retrieve Query Plan: Message: {"errors":[{"severity":"Error","location":{"start":49,"end":50},"code":"SC1001","message":"Syntax error, incorrect syntax near ','."}]}
ActivityId: ef246154-4a6b-4657-9cb3-8437a793053e, Microsoft.Azure.Documents.Common/2.14.0, Microsoft.Azure.Documents.Common/2.14.0

示例文档

{
    "device_id": "00137A100000D299",
    "timestamp": 1602127299000,
    "battery": 3.6,
    "battery_unit": "V",
    "temperature": 0.76,
    "temperature_unit": "°C",
    "humidity": 36.28,
    "humidity_unit": "%",
    "id": "87340b02-2a5d-48db-9dff-97a14785cb7f"
}

基本上这个想法是获取一些已知设备 ID 的最新时间戳,然后使用它来获取该时间戳的最新数据。

Cosmos DB SQL API 不允许基于子查询或 cross document joins 的结果进行任何类型的查找(尽管文档之间的查找 可能在 Mongo API 和图形 API) 中 - 因此您需要从客户端执行一个查询,然后在第二个查询中使用来自该查询的值。

或者您可以调整 my answer here 中的 SQL 以在单个聚合查询中完成所有操作。

正如@martin-smith 所提到的,除了简单的聚合之外,您不能对单个查询执行跨文档魔术。

添加一个更实用的说明,如果您碰巧每个时间戳只有一个数据点,那么您最简单的选择就是对每个设备执行一个简单的有序查询:

SELECT top 1 * FROM c
where c.device_id = @deviceId
order by timestamp desc

与尝试通过编写复杂的 SQL 查询来优化对服务器的 10 毫秒请求相比,发送多个简单且索引良好的查询通常更便宜且更易于维护。