Node.js Native API
Node.js Native API
The Node.js native API supports interacting with the IoTDB table model through TableSessionPool, enabling data writing, querying, non-query SQL execution, and connection management under the table model. TableSessionPool adds database context management on top of connection pool capabilities, making it suitable for accessing relational table-structured data in Node.js applications.
This document focuses on the usage of TableSessionPool, covering environment preparation, core operation steps, and common interfaces.
1. Environment Preparation
1.1 Prerequisites
Node.js >= 14.0.0
npm >= 6.0.0
IoTDB >= 2.0.11.1
1.2 Installation
- Option 1: Install via npm (Recommended)
Run the following in your Node.js project:
npm install @iotdb/client- Option 2: Build from source
To use the development version from the repository, clone the source code and install dependencies:
git clone https://github.com/apache/iotdb-client-nodejs.git
cd iotdb-client-nodejs
git checkout develop
npm ciOn Linux, macOS, or WSL:
npm run buildOn Windows PowerShell:
npm run build:esbuild
npm run build:types
New-Item -ItemType Directory -Force -Path dist\thrift\generated
Copy-Item src\thrift\generated\*.js,src\thrift\generated\*.d.ts -Destination dist\thrift\generated -ForceAfter the build completes, you can install it locally in your business project via the absolute path of the client source directory:
npm install /absolute/path/to/iotdb-client-nodejsIf you use TypeScript, no additional type declarations are required; the client ships with complete TypeScript type definitions built in.
Note: Do not use a higher-version client to connect to a lower-version server.
2. Core Steps
The three core steps of using the Node.js native API to operate the IoTDB table model are as follows:
Create a connection pool instance: initialize a
TableSessionPoolobject and configure connection parameters, database, and pool size.Execute database operations: directly perform table creation, data writes, or queries through the connection pool.
Close the connection pool resources: call
tablePool.close()when the program exits to release all connections.
The following sections describe the core development flow and do not demonstrate all parameters and interfaces. For the complete capability set, refer to the @iotdb/client source code and examples.
2.1 Create a Connection Pool Instance
2.1.1 Single-Node Connection
import { TableSessionPool } from '@iotdb/client';
const tablePool = new TableSessionPool('localhost', 6667, {
username: 'root',
password: 'root',
database: 'test',
maxPoolSize: 10,
minPoolSize: 2,
});
await tablePool.init();Here database sets the default database for the table model. Once configured, the pool uses this database context when executing queries and writes.
2.1.2 Multi-Node Connection
In a cluster environment, it is recommended to configure multiple nodes via nodeUrls. The connection pool distributes connections across nodes in a round-robin manner and tries other available nodes when a connection fails.
import { TableSessionPool } from '@iotdb/client';
const tablePool = new TableSessionPool({
nodeUrls: [
'192.168.1.100:6667',
'192.168.1.101:6667',
'192.168.1.102:6667',
],
username: 'root',
password: 'root',
database: 'test',
maxPoolSize: 10,
minPoolSize: 2,
});
await tablePool.init();Connection pool parameters can be adjusted according to business concurrency: minPoolSize is recommended to be set to the average concurrent load, while maxPoolSize is recommended to be set to the peak concurrent load with a 20% to 30% buffer; maxIdleTime is used to clean up long-idle connections, and waitTimeout controls the maximum wait time when the pool is exhausted. In production, it is recommended to monitor getPoolSize(), getAvailableSize(), and getInUseSize(), and adjust the pool size based on peak load.
2.1.3 SSL/TLS Connection
If SSL/TLS is enabled on the IoTDB server, you can enable SSL when creating the connection pool and specify certificate-related parameters.
import { TableSessionPool } from '@iotdb/client';
import * as fs from 'fs';
const tablePool = new TableSessionPool({
host: 'localhost',
port: 6667,
username: 'root',
password: 'root',
database: 'test',
enableSSL: true,
sslOptions: {
ca: fs.readFileSync('/path/to/ca.crt'),
cert: fs.readFileSync('/path/to/client.crt'),
key: fs.readFileSync('/path/to/client.key'),
rejectUnauthorized: true,
},
});
await tablePool.init();2.1.4 Write Redirection
In a multi-node IoTDB cluster, the client supports write redirection. When a write operation is sent to a non-target node, the server may return a redirection hint; the client caches the target routing and preferentially uses a more appropriate node for subsequent writes.
import { TableSessionPool } from '@iotdb/client';
const tablePool = new TableSessionPool({
nodeUrls: [
'192.168.1.100:6667',
'192.168.1.101:6667',
'192.168.1.102:6667',
],
username: 'root',
password: 'root',
database: 'test',
maxPoolSize: 10,
enableRedirection: true,
redirectCacheTTL: 300000,
});
await tablePool.init();With redirection enabled, cross-node forwarding is reduced, improving write throughput and lowering network latency.
2.2 Database Operations
2.2.1 Create Database and Table
await tablePool.executeNonQueryStatement('CREATE DATABASE IF NOT EXISTS test');
await tablePool.executeNonQueryStatement('USE test');
await tablePool.executeNonQueryStatement(`
CREATE TABLE IF NOT EXISTS device_metrics (
time TIMESTAMP TIME,
device_id STRING TAG,
region STRING ATTRIBUTE,
temperature FLOAT FIELD,
humidity FLOAT FIELD
)
`);2.2.2 Write Tablet Data
When writing in the table model, you need to specify the table name, column names, data types, timestamps, and values. The following example organizes values by column, where each array corresponds to a non-time column.
import { ColumnCategory, TSDataType } from '@iotdb/client';
await tablePool.insertTablet({
tableName: 'device_metrics',
columnNames: ['device_id', 'region', 'temperature', 'humidity'],
columnTypes: [
TSDataType.STRING,
TSDataType.STRING,
TSDataType.FLOAT,
TSDataType.FLOAT,
],
columnCategories: [
ColumnCategory.TAG,
ColumnCategory.ATTRIBUTE,
ColumnCategory.FIELD,
ColumnCategory.FIELD,
],
timestamps: [Date.now(), Date.now() + 1000],
values: [
['device_1', 'beijing', 25.5, 60.0],
['device_1', 'beijing', 26.0, 61.5],
],
});If your project does not use enums directly, columnTypes can also use data type codes.
When writing data, it is recommended to use insertTablet for batch writes to reduce network round trips. A common batch size to start benchmarking is 100 to 1000 rows, then adjust based on data volume, network, and server resources.
2.2.3 Query Data
Query results are returned via SessionDataSet. After use, call close() to release server-side query resources.
const dataSet = await tablePool.executeQueryStatement(`
SELECT time, device_id, region, temperature, humidity
FROM device_metrics
WHERE device_id = 'device_1'
`);
while (await dataSet.hasNext()) {
const row = dataSet.next();
console.log(row.getFields());
}
await dataSet.close();For small result sets, you can also use toArray() to load all results into memory:
const dataSet = await tablePool.executeQueryStatement('SHOW TABLES');
const rows = await dataSet.toArray();
console.log(rows);
await dataSet.close();2.3 Close the Connection Pool
await tablePool.close();It is recommended to uniformly close the connection pool when the application exits, scheduled tasks end, or the service is destroyed to avoid connection leaks.
3. Common Interfaces
3.1 TableSessionPool
3.1.1 Description
TableSessionPool is the recommended connection pool interface for the table model, supporting automatic session management and database context management. When calling query, write, or non-query methods, the pool automatically acquires an available session and reclaims the connection after execution.
3.1.2 Construction
| Construction | Description |
|---|---|
new TableSessionPool(host, port, config) | Traditional constructor, suitable for single-node connections |
new TableSessionPool(config) | Construct with a config object, suitable for nodeUrls multi-node configurations |
new TableSessionPool(new PoolConfigBuilder().build()) | Construct with the builder pattern, recommended for scenarios with many parameters |
3.1.3 Methods
| Method | Description |
|---|---|
init() | Initialize the connection pool |
close() | Close the connection pool and release all connections |
executeQueryStatement(sql, timeoutMs?) | Execute a query SQL, with optional query timeout |
executeNonQueryStatement(sql) | Execute a non-query SQL, such as DDL or DML |
insertTablet(tablet) | Insert table-model Tablet data |
getPoolSize() | Get the current pool size |
getAvailableSize() | Get the current number of available connections |
getInUseSize() | Get the current number of connections in use |
3.1.4 Configuration
| Option | Description |
|---|---|
host | Host address |
port | Port |
nodeUrls | Multiple node addresses in host:port format |
username | Username |
password | Password |
database | Default database |
timezone | Time zone |
fetchSize | Batch fetch size for query results |
maxPoolSize | Maximum number of connections |
minPoolSize | Minimum number of connections |
maxIdleTime | Maximum idle time in milliseconds |
waitTimeout | Wait timeout for acquiring a connection in milliseconds |
enableSSL | Whether to enable SSL |
sslOptions | SSL parameters |
enableRedirection | Whether to enable write redirection |
redirectCacheTTL | Redirection cache expiration time in milliseconds |
3.2 Tablet Parameters
Common parameters of the table-model insertTablet are as follows:
| Parameter | Description |
|---|---|
tableName | Target table name |
columnNames | List of non-time column names |
dataTypes | List of data types for non-time columns |
columnCategories | List of categories for non-time columns |
timestamps | List of timestamps |
values | List of column values, organized by column |
The order of columnNames, columnTypes, columnCategories, and values must be consistent.
4. Data Types
When inserting Tablet data, you need to specify the corresponding data type for each column. The common types supported by the Node.js client are as follows:
| Type Code | Type Name | JavaScript Type | Description |
|---|---|---|---|
0 | BOOLEAN | boolean | Boolean value |
1 | INT32 | number | 32-bit integer |
2 | INT64 | bigint | 64-bit integer |
3 | FLOAT | number | 32-bit floating point |
4 | DOUBLE | number | 64-bit floating point |
5 | TEXT | string | UTF-8 text |
8 | TIMESTAMP | Date | Millisecond-precision timestamp |
9 | DATE | Date | Date type |
10 | BLOB | Buffer | Binary data |
11 | STRING | string | UTF-8 string |
When handling INT64 values, it is recommended to use bigint in JavaScript to avoid precision loss when exceeding the safe integer range of number.
5. FAQ
Default database does not exist: If the configured
databasedoes not yet exist when the pool is initialized, executeCREATE DATABASEfirst, then explicitly executeUSE database_namebefore creating tables, querying, or writing; alternatively, create the database before initializingTableSessionPool.Column mismatch: If a column count or type mismatch occurs during writing, check whether the order and length of
columnNames,columnTypes,columnCategories, andvaluesare consistent, and confirm thatvaluesare organized by row and the table structure matches the written data.Query results consume too much memory: For large result sets, use
hasNext()andnext()to read in batches and reducefetchSize. Only usetoArray()for small result sets.Connection acquisition timeout: If waiting for an available connection times out, it usually means the pool is exhausted. Increase
waitTimeoutormaxPoolSizeaccordingly, and check whether there are query result sets that have not been closed for a long time.