NestJS连接influxdb2.x or 1.8+并读写

337 阅读2分钟

准备工作

安装依赖

npm i @influxdata/influxdb-client

创建influxdb模块和服务

nest g mo influxdb
nest g s influxdb

记得导入到app.module

influxdb中导出service

import { Module } from '@nestjs/common';
import { InfluxdbService } from './influxdb.service';

@Module({
  providers: [InfluxdbService],
  exports: [InfluxdbService]
})
export class InfluxdbModule {}

建库

http://localhost:8086

如果是初次进入会让你创建默认user、organization、bucket

创建好后会给你一个token,请务必保存token

创建Organization和Bucket

点击左侧类似头像的地方,选择Create Organization

Image.png

填写你需要写入的Organization和Bucket,然后点击CREATE

Image.png


连接并读写数据库

import { Injectable, Inject } from '@nestjs/common';
import { InfluxDB, Point } from '@influxdata/influxdb-client';
import { InfluxData, InfluxParams } from 'src/types';
import { Logger } from 'winston';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { log } from 'console';

@Injectable()
export class InfluxdbService {
    private readonly influxdb: InfluxDB;
    constructor(
        @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
    ) {

        this.influxdb = new InfluxDB({
            url: 'http://localhost:8086/',
            // 首次登录influxdb的web界面时会给的token
            // 或者在WebUI中的Load Data - API TOKENS中创建一个
            token: '不告诉你',
        });
    }
    
    // 写入influxdb
    async write(data: InfluxData) {
        try 
            // organization_ibuki: 组织名(organization)
            // suika: 存储桶名(bucket)
            const writeApi = this.influxdb.getWriteApi('organization_ibuki', 'suika');
            this.logger.info(`正在往InfluxDB写入数据`);
            
            // 将rabbitmq推送过来的数据写入influxdb
            // data: 表名(会自动建表)
            const point = new Point('data')
                .floatField('value', data.value)
                .tag('deviceId', data.deviceId.toString())
                .tag('times', data.times.toString());
                
            try {
                await writeApi.writePoint(point);
                this.logger.info('写入influxdb成功')
            } catch (error) {
                log(error);
            } finally {
                writeApi.close();
            }
        } catch (error) {
            log(error);
        }
    }
    
    // 读取influxdb
    async read(influxParams: InfluxParams) {
        const { deviceId , startTime, endTime } = influxParams;
        // 获取查询指定组织的实例
        const queryApi = this.influxdb.getQueryApi('organization_ibuki');            
        const start = new Date(startTime).toISOString();
        const end = new Date(endTime).toISOString();
        // 新建flux查询语句,range: 事件范围, filter: 过滤条件
        let fluxQuery = `from(bucket: "tlink") |> range(start: ${start}, stop: ${end}) |> filter(fn: (r) => r._measurement == "data"`;
        if (deviceId) {
            fluxQuery += ` and r.deviceId == "${deviceId}"`;
        }
        fluxQuery += ')';

        // 查询结果
        const result = [];
        if(deviceId){
            await new Promise((resolve, reject) => {
                // queryRows执行influxdb查询,接收一个flux查询语句,返回一个Observable<FluxTable>对象
                queryApi.queryRows(fluxQuery, {
                    next(row, tableMeta) {
                        const o = tableMeta.toObject(row)
                        result.push(o);
                    },
                    error(error) {
                        reject(error)
                    },
                    complete() {
                        resolve(result)
                    },
                })
            });
            return result;
        }else{
            return {
                flag: '01',
                message: '没有设备id或传感器id'
            };
        }
    }
}

然后在其他需要用到的地方调用这哥俩就行了

关于Flux语句怎么写建议看官方文档,或者问AI

至于测试就懒得放上来了,跟着走一遍准能执行

(日期2023-12-7,influxdb2.7.4,influxdb-client1.33.2)