You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:45:33