教程第4部分:键值商店 - 数据流
#serverless #node #database #iot

欢迎使用codehooks.io无服务器Node.js后端的key-value database tutorialkey-value database tutorial的Part-4 。在这一部分中,我们将重点介绍如何在key-value database中使用多个键值对。

codehooks.io键值数据库将所有键存储为排序的字符串索引。如果您需要作为组或键值的段来存储和检索多个值,这是一个非常有用的功能。

本文也可以在the official codehooks.io website

上可用

物联网设备 - 时间序列数据示例

为了说明此功能,我们将创建一个示例用例,以捕获来自多个IoT devices的数据。在此示例中,每个物联网设备将其位置,标识和观察值发送到特定的REST API网络端点。

例如,“ Alpha区域西”中的温度传感器设备每分钟报告其值。 “ Beta区域西”中的风力传感器每小时报告其值,依此类推。

为了确保我们可以有效地访问和处理观察数据集,我们将创建一个键字符串组合,该组合将所有必要的信息捕获在一个唯一的键值对中。

为了说明这个概念,让您想象一系列的IoT设备观测值,如下示例所示。

'/Alpha/West/density/2023-01-09T10:14:00.495Z'  => '4.4191'
'/Alpha/West/humidity/2023-01-09T17:01:00.821Z' => '0.7539'
'/Alpha/West/temp/2023-01-09T21:15:00.450Z'     => '87.100'
'/Beta/West/wind/2023-01-19T21:57:00.316Z'      => '5.9477'
...

现在,我们了解了IoT数据库的概念,让我们开始开发IoT传感器的后端API。

我们将创建一个无服务器REST API端点,以接收许多IoT设备的观察值。 API将使用一个逻辑密钥存储每个观察值,该密钥可有效地创建一个具有数据点的time series database,我们可以在应用程序中探索和使用。

让我们开始创建第一个API以从设备接收数据观察。

REST API端点发布单个观察结果

REST API路由为给定的设备,区域,位置和设备提供3个参数。
邮局必须包含实际的设备观察数据点。
例如:

POST /observation/North/Plaza/humid03 

{"observation": "4.02"}

路由参数与时间戳合并为一个唯一键,该键为数据点提供正确的时间序列。下表显示了一些示例设备观测值。

IOT设备时间序列 数据点
nastt/builza/temp01/22222222222222222222221Z 21.4
/north/plaza01/humid3/2023-02-23T05:23:11.306Z 12.5
/east/builingb/temp02/2023-02-22t18:32:38.991z 19.0

下面的无服务器函数实现了REST API端点路由,该路由可以从设备接收数据并将其插入到键值数据库中。

app.post('/observation/:region/:location/:device', async (req, res) => {
    const {region, location, device} = req.params;
    const {observation} = req.body;    
    const key = `/${region}/${location}/${device}/${new Date().toISOString()}`;
    // string key e.g. '/North/Plaza/humid03/2023-02-23T05:23:11.306Z'
    const conn = await Datastore.open();
    const result = await conn.set(key, observation);
    console.log(result)
    res.status(201).end('Data received ok');
})

用卷曲测试REST API。

curl -X POST \
  'https://<YOUR_DATABASE_ID>.api.codehooks.io/dev/observation/East/BuilingA/temp01' \
  --header 'x-apikey: <YOUR_API_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "observation": "21.4"
}'

使用cli命令koude0检查您的项目API端点和卷曲示例。

使用CLI检查键值数据库

Codehooks CLI可用于管理键值数据库基本操作,getsetdel。例如,要检索East位置的所有观察值,您可以运行以下命令:

coho get '/East*'

这将列出键值数据库中的所有匹配键,如下面显示的示例输出。

{
  key: '/East/BuilingA/temp01/2023-02-23T05:48:19.646Z',
  value: '21.4'
}
{
  key: '/East/BuilingA/temp01/2023-02-23T05:49:06.614Z',
  value: '20.0'
}

2 keys

终点获取观测值

与上面的CLI示例相似,我们可以使用database API getAll方法来检索与特定键的开始段相匹配的所有键值对。在此示例中,我们正在生产CSV data format用于简易电子表格分析等。

app.get('/observations/:prefix', async (req, res) => {
    const conn = await Datastore.open();
    const {prefix} = req.params;
    let count = 0;
    res.set('content-type', 'text/csv');
    res.write('Device, Data\n');
    const stream = conn.getAll(`/${prefix}`);
    stream.on('data', (data) => {
        const outString = `"${data.key}", ${data.val}\n`;
        count++
        res.write(outString);
    }).on('end', () => {
        res.end();        
    })
})

再次用卷曲测试API。

curl -X GET \
  'https://<YOUR_DATABASE_ID>.api.codehooks.io/dev/observations/Alpha' \
  --header 'x-apikey: <YOUR_API_TOKEN>' \
Device, Data
"/Alpha/Center/decibel/2023-01-09T11:11:31.218Z", 2.3428
"/Alpha/Center/decibel/2023-01-09T11:12:01.050Z", 6.0632
"/Alpha/Center/decibel/2023-01-09T13:13:30.541Z", 0.7196
"/Alpha/Center/decibel/2023-01-09T15:23:00.589Z", 9.7232
"/Alpha/Center/decibel/2023-01-09T15:34:00.520Z", 5.0089
"/Alpha/Center/decibel/2023-01-09T17:04:00.942Z", 9.1861

完成源代码

我们的Io​​T后端应用程序的完整源代码如下所示。

// index.js
import { app, Datastore } from 'codehooks-js' // Standard JS lib for express style code

// list a serie of IoT device observations
app.get('/observations/:prefix', async (req, res) => {
    const conn = await Datastore.open();
    const {prefix} = req.params;
    let count = 0;
    res.set('content-type', 'text/csv');
    res.write('Device, Data\n');
    const stream = conn.getAll(`/${prefix}`);
    stream.on('data', (data) => {
        const outString = `"${data.key}", ${data.val}\n`;
        count++
        res.write(outString);
    }).on('end', () => {
        res.write(`Result: ${count}`);
        res.end();        
    })
})

// register a new IoT device observation
app.post('/observation/:region/:location/:device', async (req, res) => {
    const {region, location, device} = req.params;
    const {observation} = req.body;
    // string key e.g. '/North/Plaza/humid03/2023-02-23T05:23:11.306Z'
    const key = `/${region}/${location}/${device}/${new Date().toISOString()}`;
    const conn = await Datastore.open();
    const result = await conn.set(key, observation);
    console.log(result)
    res.status(201).end('Data received ok');
})

export default app.init(); // Bind functions to the serverless cloud

键值商店教程的第4部分已显示如何将智能键与数据库流功能相结合,以使用codehooks.io创建一种IOT时间序列数据库。

在我们即将推出的教程 part-5中:使用TTL选项管理数据,我们将探索如何使用“ live limive(ttl)功能”删除 old> old old 键值数据库中的数据。