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

MongoDB双集合关联:如何根据餐厅dishes外键获取菜品及配置前端Fetch?

获取指定餐厅的关联菜品对象

一、后端接口设计与实现

首先需要在后端新增接口,用于根据餐厅ID查询其关联的菜品。以下是Node.js + Express + MongoDB的实现示例:

方式1:分步查询

const { ObjectId } = require('mongodb');
const express = require('express');
const app = express();

// 假设已连接MongoDB,db为数据库实例
app.get('/api/restaurants/:restaurantId/dishes', async (req, res) => {
  try {
    const { restaurantId } = req.params;
    // 查询指定餐厅
    const restaurant = await db.collection('restaurants').findOne({ _id: ObjectId(restaurantId) });
    if (!restaurant) {
      return res.status(404).json({ message: '餐厅不存在' });
    }
    // 根据餐厅的dishes外键数组查询对应菜品
    const dishIds = restaurant.dishes.map(id => ObjectId(id));
    const dishes = await db.collection('dishes').find({ _id: { $in: dishIds } }).toArray();
    res.json(dishes);
  } catch (err) {
    res.status(500).json({ message: '服务器错误', error: err.message });
  }
});

方式2:使用MongoDB聚合查询(更高效)

const { ObjectId } = require('mongodb');
const express = require('express');
const app = express();

app.get('/api/restaurants/:restaurantId/dishes', async (req, res) => {
  try {
    const { restaurantId } = req.params;
    // 用$lookup关联两个集合
    const [result] = await db.collection('restaurants').aggregate([
      { $match: { _id: ObjectId(restaurantId) } },
      {
        $lookup: {
          from: 'dishes',       // 关联的集合名
          localField: 'dishes', // 餐厅集合中存储外键的字段
          foreignField: '_id',  // 菜品集合中对应的主键字段
          as: 'restaurantDishes'// 输出的字段名
        }
      },
      { $project: { restaurantDishes: 1, _id: 0 } } // 只返回菜品数据
    ]).toArray();
    
    if (!result) {
      return res.status(404).json({ message: '餐厅不存在' });
    }
    res.json(result.restaurantDishes);
  } catch (err) {
    res.status(500).json({ message: '服务器错误', error: err.message });
  }
});

二、前端Fetch请求调整

前端需要先获取到指定餐厅的ID(比如从餐厅列表接口、路由参数或页面交互中获取),然后构造正确的请求URL:

// 封装获取餐厅菜品的函数,传入餐厅ID作为参数
const fetchRestaurantDishes = async (restaurantId) => {
  try {
    // 拼接包含餐厅ID的请求URL
    const url = `http://localhost:3001/api/restaurants/${restaurantId}/dishes`;
    const response = await fetch(url);
    
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    
    const dishes = await response.json();
    console.log('餐厅菜品:', dishes);
    return dishes;
  } catch (error) {
    console.error('获取菜品出错:', error);
    throw error;
  }
};

// 调用示例:传入目标餐厅的ID
fetchRestaurantDishes("63a877556959f4b58c5042cf");

说明

  • 如果是从餐厅列表进入详情页,可以在点击餐厅时将该餐厅的_id传递给这个函数;
  • 如果是单页应用,也可以从路由参数中读取餐厅ID(比如/restaurants/:id中的id)。

内容的提问来源于stack exchange,提问作者abeer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:20:09