Node.js 中将查询数据拼接为 JSON 的实用指南
在 Node.js 开发中,将数据库或其他数据源查询到的结果转换为 JSON 格式是一项常见任务,本文将详细介绍几种在 Node.js 中实现数据查询结果拼接为 JSON 的方法,包括原生方式、使用 ORM 框架以及处理复杂数据结构的情况。
原生方式处理查询结果
从 MySQL 查询结果构建 JSON
使用 mysql 或 mysql2 模块时,查询结果已经是对象数组,可以直接转换为 JSON:
const mysql = require('mysql2/promise');
async function getDataAsJson() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'testdb'
});
const [rows] = await connection.execute('SELECT id, name, email FROM users');
// 直接转换为 JSON 字符串
const jsonString = JSON.stringify(rows);
console.log(jsonString);
// 或者保持对象格式
const jsonData = rows;
console.log(jsonData);
await connection.end();
}
从 MongoDB 查询结果构建 JSON
MongoDB 的查询结果本身就是 BSON(二进制 JSON),可以轻松转换为 JSON:
const { MongoClient } = require('mongodb');
async function getMongoDataAsJson() {
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const db = client.db('testdb');
const collection = db.collection('users');
const cursor = collection.find({});
const results = await cursor.toArray();
// MongoDB 结果已经是对象数组,可直接转换
const jsonString = JSON.stringify(results);
console.log(jsonString);
await client.close();
}
使用 ORM 框架处理
Sequelize (SQL 数据库)
Sequelize 是流行的 Node.js ORM,查询结果可以直接转换为 JSON:
const { Sequelize, DataTypes, Op } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');
const User = sequelize.define('User', {
name: DataTypes.STRING,
email: DataTypes.STRING
});
async function getUsersAsJson() {
await sequelize.sync();
// 查询并获取 JSON 结果
const users = await User.findAll({
attributes: ['id', 'name', 'email'],
where: {
id: {
[Op.gt]: 1
}
}
});
// 转换为 JSON
const jsonData = users.map(user => user.toJSON());
console.log(JSON.stringify(jsonData, null, 2));
// 或者使用 get 方法
const jsonData2 = users.map(user => user.get({ plain: true }));
console.log(JSON.stringify(jsonData2, null, 2));
}
Mongoose (MongoDB)
Mongoose 是 MongoDB 的 ODM,同样可以轻松获取 JSON 数据:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String
});
const User = mongoose.model('User', userSchema);
async function getUsersAsJson() {
await mongoose.connect('mongodb://localhost:27017/testdb');
const users = await User.find({}).select('name email -_id');
// 转换为 JSON
const jsonData = users.map(user => user.toJSON());
console.log(JSON.stringify(jsonData, null, 2));
// 或者使用 toObject 方法
const jsonData2 = users.map(user => user.toObject());
console.log(JSON.stringify(jsonData2, null, 2));
await mongoose.disconnect();
}
处理复杂数据结构
关联数据拼接 JSON
当需要处理关联数据时,可以使用 include (Sequelize) 或 populate (Mongoose):
// Sequelize 示例
const Post = sequelize.define('Post', { DataTypes.STRING,
content: DataTypes.TEXT
});
User.hasMany(Post);
Post.belongsTo(User);
async function getUsersWithPostsAsJson() {
const users = await User.findAll({
include: [{
model: Post,
attributes: ['title', 'content']
}]
});
const jsonData = users.map(user => user.get({ plain: true }));
console.log(JSON.stringify(jsonData, null, 2));
}
自定义 JSON 结构
有时需要自定义 JSON 结构,可以使用 map 和对象展开:
async function getCustomJson() {
const [rows] = await connection.execute('SELECT id, name, email FROM users');
const customJson = rows.map(user => ({
userId: user.id,
fullName: user.name,
contact: {
email: user.email
},
metadata: {
createdAt: new Date().toISOString(),
source: 'database'
}
}));
console.log(JSON.stringify(customJson, null, 2));
}
性能优化建议
- 只查询需要的字段:使用
SELECT指定字段而不是SELECT * - 分页处理大数据集:避免一次性加载过多数据
- 使用流式处理:对于大数据集,考虑使用流式处理
- 缓存常用查询结果:减少重复数据库查询
// 分页示例
async function getPagedDataAsJson(page = 1, limit = 10) {
const offset = (page - 1) * limit;
const [rows] = await connection.execute(
'SELECT id, name, email FROM users LIMIT ? OFFSET ?',
[limit, offset]
);
return {
page,
limit,
total: rows.length,
data: rows
};
}
常见问题与解决方案
-
日期格式问题:JSON.stringify 默认会格式化日期,可以使用
replacer函数自定义const jsonString = JSON.stringify(data, (key, value) => { if (typeof value === 'date') { return value.toISOString(); } return value; }); -
循环引用问题:对象间存在循环引用时,使用
replacer函数或第三方库如flattedconst { stringify } = require('flatted'); const jsonString = stringify(data); -
大型数据集内存问题:使用流式处理或分块处理
const { Transform } = require('stream'); class JsonTransform extends Transform { constructor() { super({ objectMode: true }); this.firstChunk = true; } _transform(chunk, encoding, callback) { if (this.firstChunk) { this.push('[\n'); this.firstChunk = false; } else { this.push(',\n'); } this.push(JSON.stringify(chunk)); callback(); } _flush(callback) { this.push('\n]'); callback(); } } // 使用示例 connection.queryStream('SELECT * FROM users') .pipe(new JsonTransform()) .pipe(process.stdout);
在 Node.js 中将查询数据转换为 JSON 的方法多种多样,根据具体需求和技术栈选择合适的方式:
- 简单查询:直接使用
JSON.stringify()或保持对象格式 - SQL 数据库:可以使用原生查询或 Sequelize 等 ORM
- NoSQL 数据库:可以使用原生查询或 Mongoose 等 ODM
- 复杂数据结构:使用关联查询和自定义映射
- 性能关键场景:考虑分页、流式处理和字段选择
这些技巧将帮助你在 Node.js 应用中高效地处理和输出 JSON 数据,构建更强大的 API 和服务。



还没有评论,来说两句吧...