我使用Azure CosmosDB,模型包含Id和createtime属性。我要做的是在时间间隔内计数条目。我看了看如何使用LINQ实现它,但找不到解决方案。我使用的是SQL。这是我尝试过的:
SELECT VALUE COUNT(1)
FROM root WHERE (root["DeviceId"] = "myId")
GROUP BY (root["creationTime"] >= 50 and root["creationTime"] < 60),
(root["creationTime"] >= 40 and root["creationTime"] < 50),
(root["creationTime"] >= 30 and root["creationTime"] < 40),
(root["creationTime"] >= 20 and root["creationTime"] < 30)
请记住,我显示的值是用于显示的。正确的结果是一个包含计数值的数组,例如[5,0,3,6]">=50 and <60";= 5, ">=40; <50";= 0, ">=30;40";= 3,">=20; <30";
= 6日这个查询的问题是:
- 结果的顺序与查询不匹配,我得到[3,6,5]
- 如果count为0,它将被驳回
- 如果范围没有覆盖所有计数,我也会得到差异作为结果。假设DB包含以下范围:从5到55,因为我查询从20到60,所以我也得到了从5到19的范围。将所有计数加起来将得到总数。
有没有更好的方法来实现这一点,而不是在每个间隔上迭代,然后计算条目的数量。
谢谢你的帮助。
如果您正在执行相同分区查询. .
. .那么你可以通过来解决这个问题,包括select
的范围描述符(假设实际的谓词更复杂,并且mod或函数或其他此类技巧与手头的问题无关),例如:
SELECT
(root.creationTime >= 50 and root.creationTime < 60) as V50To60,
(root.creationTime >= 40 and root.creationTime < 50) as V40To50,
(root.creationTime >= 30 and root.creationTime < 40) as V30To40,
(root.creationTime >= 20 and root.creationTime < 30) as V20To30,
COUNT(1) as total
FROM root
WHERE root.Id = "myId"
GROUP BY
(root.creationTime >= 50 and root.creationTime < 60),
(root.creationTime >= 40 and root.creationTime < 50),
(root.creationTime >= 30 and root.creationTime < 40),
(root.creationTime >= 20 and root.creationTime < 30)
这样客户端可以根据需要排序结果并确定任何缺失的组。请注意,CosmosDB不支持order by
的group by
查询(目前),所以你必须在客户端这样做。
如果这是一个跨分区查询. .
. .那么您只能在输出中有一个VALUE
聚合,这意味着您无法从查询中获得组描述符信息。而且,CosmosDB不支持非相关连接,所以我倾向于认为也不可能有神奇的连接技巧。即使有,我也怀疑它是否美观和可维护。
所以,我猜你被迫做多个查询,每个范围一个,并在客户端合并结果。这很可能是简单而有效的(只要您有索引覆盖它),尽管不同的查询不会描述同一时刻。
如果你真的真的需要从同一时间点的总数,那么你可能需要保留一个索引文档用于跟踪范围总数(即使用更改提要)并查询该索引文档。