我在MERN堆栈的Electron 商务平台上工作.在我的项目中,我有三个架构:User、Product和Cart.购物车架构同时引用用户架构和产品架构.

以下是我的简化架构 struct :

CartModel.js

const mongoose = require("mongoose");
const { Schema, model } = mongoose;

const cartSchema = new Schema(
  {
    user: { type: Schema.Types.ObjectId, ref: "User", required: true },
    product: { type: Schema.Types.ObjectId, ref: "Product", required: true },
    unit: { type: Number, required: true },
  },
  { timestamps: true, versionKey: false }
);

const cartModel = model("Cart", cartSchema);
module.exports = cartModel;

ProductModel.js

const mongoose = require("mongoose");
const { Schema, model } = mongoose;

const productSchema = new Schema(
  {
    title: String,
    short_des: String,
    price: Number,
    discount_price: Number,
    image: String,
    stock: String,
    star: String,
  },
  { timestamps: true, versionKey: false }
);

const productModel = model("Product", productSchema);

module.exports = productModel;

UserModel.js

const mongoose = require("mongoose");
const { Schema, model } = mongoose;

const userSchema = new Schema(
  {
    name: { type: String, required: true },
    email: { type: String, unique: true, required: true },
    password: { type: String, required: true },
  },
  { timestamps: true, versionKey: false }
);

const userModel = model("User", userSchema);

module.exports = userModel;

我的问题是,在我的购物车控制器,我试图定义一个查询加入购物车,用户和产品模型,并试图提取特定的信息,但my query isn't working as expected.

我需要提取按用户分组的每个产品的以下信息:

  • 购物车对象ID和单位
  • 用户名和邮箱
  • 产品名称和价格

我try 在数组中返回结果,这样我就可以在我的react前端中使用map方法来显示数据.

CartController.js

exports.cartList = async (req, res) => {
  try {
    let userId = new mongoose.Types.ObjectId(req.user._id);

    let result = await cartModel.aggregate([
      { $match: { user: userId } },
      {
        $lookup: {
          from: "users", // Name of the User model collection
          localField: "user",
          foreignField: "_id",
          as: "userDetails",
        },
      },
      {
        $lookup: {
          from: "products", // Name of the Product model collection
          localField: "product",
          foreignField: "_id",
          as: "productDetails",
        },
      },
      {
        $group: {
          _id: "$user",
        },
      },
    ]);
    res.status(200).json({ status: true, data: result });
  } catch (error) {
    res.status(200).json({ status: false, data: error.message });
  }
};

购物车模型数据示例如下

{
  "_id": {
    "$oid": "6592be024fc8de3f1771a9e1"
  },
  "product": {
    "$oid": "657fab1586f102e3657bf034"
  },
  "user": {
    "$oid": "6559696bfa9b7df357161a81"
  },
  "createdAt": {
    "$date": "2024-01-01T13:28:34.452Z"
  },
  "unit": 4,
  "updatedAt": {
    "$date": "2024-01-01T13:28:46.865Z"
  }
},
{
  "_id": {
    "$oid": "6592dc014fc8de3f1771bc3f"
  },
  "product": {
    "$oid": "65801d5e2c366e8773ada21f"
  },
  "user": {
    "$oid": "6559696bfa9b7df357161a81"
  },
  "createdAt": {
    "$date": "2024-01-01T15:36:33.420Z"
  },
  "unit": 3,
  "updatedAt": {
    "$date": "2024-01-01T15:36:37.161Z"
  }
}

谁可以提供一个聚合查询的指导或示例,该聚合查询以适合在Reaction中映射的格式从多个集合(购物车、用户和产品)中检索指定的信息?如有任何帮助或建议,我们将不胜感激.谢谢!

推荐答案

您可以执行以下操作:

一百:

这将为您提供一个由1个对象组成的数组,这些对象按用户分组,具有nameemailcarts属性.carts属性是用户拥有的所有购物车,每个购物车都有您需要的特定字段.这样你就可以映射carts号公路了.

const result = await cartModel.aggregate([
  {
    $match: {
      user: userId
    }
  },
  {
    $lookup: {
      from: "users",
      localField: "user",
      foreignField: "_id",
      as: "userDetails"
    }
  },
  {
    $unwind: "$userDetails"
  },
  {
    $lookup: {
      from: "products",
      localField: "product",
      foreignField: "_id",
      as: "productDetails"
    }
  },
  {
    $unwind: "$productDetails"
  },
  {
    $group: {
      _id: "$userDetails._id",
      name: {
        $first: "$userDetails.name"
      },
      email: {
        $first: "$userDetails.email"
      },
      carts: {
        $push: {
          cart_id: "$_id",
          product: "$productDetails",
          unit: "$unit"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      name: 1,
      email: 1,
      unit: 1,
      "carts.cart_id": 1,
      "carts.product": {
        price: 1,
        title: 1
      }
    }
  }
])

有关工作示例,请参见HERE.

一百:

这将为您提供一个由1个对象组成的数组,这些对象按用户分组,但只有一个carts属性.这将是用户拥有的所有购物车的数组,但这一次,每个购物车都将包含用户详细信息,以防您在前端循环时需要它们.

const result = await cartModel.aggregate([
  {
    $match: {
      user: userId
    }
  },
  {
    $lookup: {
      from: "users",
      localField: "user",
      foreignField: "_id",
      as: "userDetails"
    }
  },
  {
    $unwind: "$userDetails"
  },
  {
    $lookup: {
      from: "products",
      localField: "product",
      foreignField: "_id",
      as: "productDetails"
    }
  },
  {
    $unwind: "$productDetails"
  },
  {
    $group: {
      _id: "$userDetails._id",
      carts: {
        $push: {
          cart_id: "$_id",
          product: "$productDetails",
          unit: "$unit",
          user: "$userDetails"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      unit: 1,
      "carts.cart_id": 1,
      "carts.product": {
        price: 1,
        title: 1
      },
      "carts.user": {
        email: 1,
        name: 1
      }
    }
  }
])

HERE章一个工作的例子

Option 3:

由于您使用的是userproduct属性的参考文档,因此可以只使用Model.populate(),如下所示:

const result = await cartModel.find({user: userId})
.populate('user', 'name email -_id')
.populate('product', 'title price -_id')
.select('unit');

Mongodb相关问答推荐

Mongo如何找到字段排除特殊字符

在MongoDB中,如何使用$in来匹配存储在数组变量中的值

如何使用MongoDB对子文档进行条件投影?

在数组对象 Mongodb 中仅 Select 需要的数组

如何在 MongoDB 中对字段进行自定义排序

Mongodb,在一个查询中用正则表达式更新部分字符串

如何修改 mongodb 中嵌套对象数组中的字段名称/键?

MongoDB:插入重复键更新

.insertOne 不是函数

指定字段对于 MongoDB 是transient瞬态的,但对于 RestController 不是

使用 MongoDb 处理迁移

如何在任意深度查找 MongoDB 字段名称

如何在 Mongoose 中更新数组值

如何使用 angular.js 推送通知?

MongoDB count() 未定义

MongoDB - 聚合 - 获取数组中的唯一项

如何通过mongoose更新 mongodb 中的对象?

MongoError:failed to connect to server [localhost:27017] on first connect

Meteor 发布/订阅独特客户端集合的策略

全局初始化失败:BadValue Invalid or no user locale set.请确保正确设置 LANG 和/或 LC_* 环境变量