sql - 如何使用 SQL 获取 CosmosDB 中每个项目的最新记录
问题描述
我有一个类似于
"id": "uuid",
"deviceId": "uuid",
"message": {
"content": "string",
"ts": 1
},
"data": {
"temperature": 21
}
我想为每个“deviceId”获取最新的“数据”(使用 message.ts 作为时间戳)。
到目前为止,我已经设法使用查询按时间戳顺序取回数据,
SELECT c.deviceId, c.message.ts, c.data FROM c ORDER BY c.message.ts DESC
但我不知道如何删除重复的设备记录。
这可以在 CosmosDB SQL 引擎中完成吗?
解决方案
您可以采取的另一条路线是在 CosmosDb 中使用触发器函数。这样做的好处是您不需要部署 Azure 函数,只需使用 SQL 即可获取最新项目。例如,当你得到一个新的项目时,你可以使用预触发器来设置一个字段,如下所示:latest = true
,同时将上一个最近的项目的最新字段更改为 false。然后,您的 SQL 查询将只需要WHERE latest = true
返回每个项目的最新记录。这是一个具有一般思想的触发函数:
function setLatest() {
var context = getContext();
var request = context.getRequest();
// item to be created in the current operation
var itemToCreate = request.getBody();
// validate properties
if (!("latest" in itemToCreate)) {
itemToCreate["latest"] = true;
}
// update the old latest to false
removeCurrentLatest(itemToCreate["id"],..., );
// save the newer item that will be created
request.setBody(itemToCreate);
}
function removeCurrentLatest(id, ...) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
// Get the document. We keep it in the same collection.
var isAccepted = collection.queryDocuments
(collectionLink, `SELECT * FROM root r WHERE r.id = "${id}" AND .... AND r.latest = true`,
function (err, feed, options) {
if (err) throw err;
if (feed && feed[0] != null)
{
var oldDoc = feed[0];
oldDoc.latest = false;
var isAccepted = collection.replaceDocument(oldDoc._self, oldDoc, function (err) {
if (err) throw err;
});
if (!isAccepted) throw new Error("The call replaceDocument(oldDoc) returned false.");
}
});
if (!isAccepted) throw new Error("The call queryDocuments for oldDoc returned false.");
}
我已经删除了您可能想要包含的一些其他条件,以确保您选择正确的项目先前版本 - 希望如何为您的特定资产添加这些条件应该很明显。这是一篇关于在 CosmosDB 中使用触发器的优秀文章:http: //www.johndowns.co.nz/blog/2018/1/30/cosmos-db-server-side-programming-with-typescript-part-4-triggers
推荐阅读
- java - jedis 正确管理连接
- javascript - 如何将分数显示为可以从 Javascript 更新的 HTML 标签?
- python - Plotly 绘图未在 jupyter lab html 中显示,但会在 vscode 中显示
- php - 将 WooCommerce 通知显示为警报弹出窗口
- java - Apache Camel:在可执行 jar(bootJar)中执行 bean 时出错
- android - 元素未在 Xamarin Forms Android 自定义渲染器中显示
- javascript - 使用 react-native 显示来自 firebase 存储的所有视频
- machine-learning - 预测不等于图像数量
- sql - 在查询的输出中追加一行到最后一行
- spring-boot - Spring Boot JPA 安全概念