如何在MongoDB+Node.js API中展示集合的所有标签字段值列表
问题描述
我正在使用MongoDB和Node.js开发一个展示广告集合的API,需要以JSON格式输出该集合包含的所有标签列表(示例:'home', 'mobile', 'motor')。以下是数据库初始化代码:
const readline = require('readline'); const Product = require('./models/Product'); async function main() { const advance = await question('Are you sure to continue with the deletion of the database? (yes or no) ') if (!advance) { process.exit(); } const connection = require('./lib/connectMongoose') await initProducts(); connection.close(); } async function initProducts() { const deleted = await Product.deleteMany(); console.log(`Remove ${deleted.deletedCount} products.`); const inserted = await Product.insertMany([ {name: 'Table', sale: true, price: 150, photo: 'Table.png', tags: ['home']}, {name: 'Iphone 13 pro', sale: false, price: 950, photo: 'Iphone 13 pro.png', tags: ['mobile']}, {name: 'Car Mini Cooper', sale: true, price: 1000, photo: 'Car Mini Cooper.png', tags: ['motor']} ]); console.log(`Create ${inserted.length} products.`) } main().catch(err => console.log('Hubo un error', err)) function question(text) { return new Promise((resolve, reject) => { const interface = readline.createInterface({ input: process.stdin, output: process.stdout }); interface.question(text, answer => { interface.close(); if (answer.toLowerCase() === 'yes') { resolve(true); return; } resolve(false); }) }) }
现寻求合适的MongoDB方法,实现当API路由被调用时,返回包含集合所有标签的JSON数据。
解决方案
要获取集合中所有不重复的标签,有两种高效的MongoDB方法可选:
方法一:使用distinct快捷方法
distinct是MongoDB专门用于提取字段去重值的API,针对数组字段会自动展开并去重,代码简洁高效:
const express = require('express'); const router = express.Router(); const Product = require('./models/Product'); // 获取所有标签的API路由 router.get('/tags', async (req, res) => { try { // 直接调用distinct获取tags字段的所有不重复值 const tags = await Product.distinct('tags'); res.json(tags); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;
调用该路由后,会直接返回格式为["home", "mobile", "motor"]的JSON数据,完全符合需求。
方法二:使用聚合查询(适用于更复杂的场景)
如果后续需要对标签进行额外处理(比如统计标签出现次数),可以用聚合查询:
router.get('/tags', async (req, res) => { try { const result = await Product.aggregate([ // 将每个文档的tags数组拆分为单个文档 { $unwind: '$tags' }, // 分组收集所有不重复的标签 { $group: { _id: null, tags: { $addToSet: '$tags' } } }, // 移除不需要的_id字段 { $project: { _id: 0 } } ]); // 提取tags数组,为空时返回空数组 const tags = result.length ? result[0].tags : []; res.json(tags); } catch (err) { res.status(500).json({ error: err.message }); } });
说明
distinct方法是最适合当前需求的方案,代码量少且性能优异。- 聚合查询则提供了更强的扩展性,适合后续有复杂数据处理需求的场景。
内容的提问来源于stack exchange,提问作者Emily Heredia
相关产品推荐
相关产品推荐

