猫鼬在 populate() 方法后返回空数组

斯特凡·格奥尔基耶夫

在过去的 3-4 个小时里,我把头撞在墙上,并在 StackOverflow 上查看了无数文章,但无法得到我的回应以正确填充数组。将 Express.js 与 Typescript、MongoDB 和猫鼬一起使用。问题是当我收到所有订单的响应时,我的有序行数组为空,即使我可以检查并查看MongoDB地图集中的 ID。以下是实际响应:

[
  {
    "orderedlines": [],
    "_id": "6251c61f7385c349f88fe95a",
    "userId": {
      "favourites": [
        "623b39e684b9baf1109053f8",
        "623b3afada0e7828602c78df",
        "623b3b49da0e7828602c78e7",
        "623b39ba84b9baf1109053f7",
        "623b3b59da0e7828602c78e9"
      ],
      "_id": "62326179b9c85d3fc833d686",
      "orders": [],
      "email": "[email protected]",
      "username": "stef1222",
      "password": "$2b$10$3e5Y/IoyrcJHH3ud6Mn/I.8PfBm2JrEKHwYRd8cQwUaAdz.YkKSMa",
      "firstName": "Stefan",
      "lastName": "Georgiev",
      "image": "https://res.cloudinary.com/dtggdx3hc/image/upload/v1648046254/deqr4chfysogoppafdug.png",
      "isAdmin": false,
      "hasWriteAccess": false,
      "__v": 0
    },
    "totalPrice": 121.99,
    "__v": 0
  }
]

如上所示,我的 userId 已成功填充其所有属性,但orderedlines 无法填充,它作为空数组返回。如果我删除 .populate() 它会返回一个带有 id 的对象数组

我假设发生问题的 orderServices 中的 findOrdersForUserId 函数

const findOrdersForUserId = async (
  userId: string
): Promise<OrderDocument[]> => {
  const ordersToReturn = await Order.find({ userId: userId })
    .sort({ _id: 1 })
    .populate('userId')
    .populate({path:'orderedlines', model:OrderLine})
  return ordersToReturn
}

这是我的订单模型:

import mongoose, { Document } from 'mongoose'

export type OrderLine = {
  orderlineId: string
}

export type OrderDocument = Document & {
  userId: string
  orderedlines: OrderLine[]
  totalPrice: number
}

const orderSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  totalPrice: Number,
  orderedlines: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'OrderLine',
    },
  ],
})

export default mongoose.model<OrderDocument>('Order', orderSchema, 'orders')

我的 OrderLine 模型:

import mongoose, { Document } from 'mongoose'

export type OrderLineDocument = Document & {
  productId: string
  userId: string
  quantity: number
  price: number
}

const orderLineSchema = new mongoose.Schema({
  quantity: { type: Number, default: 1 },
  price: Number,
  productId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Product',
    required: true,
  },
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true,
  },
})

export default mongoose.model<OrderLineDocument>('OrderLine', orderLineSchema, 'orderlines')

Mongoose version used: [email protected]
Node version: v16.13.0
Mongo Shell version: v5.0.6
Express version: [email protected]

我会列出一些我试图解决我的问题但没有成功的文章:

  1. Mongoose 填充返回空数组
  2. Mongoose populate() 返回空数组
  3. Mongoose populate() 返回没有错误的空数组
  4. Mongoose Populate 不适用于 ObjectIds 数组
  5. 填充方法未填充我的评论数组
  6. Mongoose 填充不填充数组
  7. Mongoose 填充不填充数组并始终返回一个空数组

编辑:所有代码都是来自设置为私有的 repo 的 fork 的一部分。我不确定如何共享对 fork 的访问/链接以便更好地预览代码。如果您想查看其他内容或更具体的代码部分,请赐教。

斯特凡·格奥尔基耶夫

回答我自己的问题,因为我为此付出了很多努力,并希望帮助未来的人阅读这个问题。首先,真正重要的问题可能是您没有指定集合名称。为了指定集合名称,在模型创建中添加第三个参数,如下所示:

export default mongoose.model<OrderLineDocument>('OrderLine',orderLineSchema,'orderLines')

在第三个参数之前,mongoose 创建了一个带有小写复数模型名称的集合名称 - orderlines但是当我试图填充我的回复时,我指的是带有大写 L 的 orderLines。因此,请务必在 MongoDB Shell/MongoDB Atlas 中指定您的集合名称或检查您的集合名称。

其次。始终检查要填充的数组/对象的 _id 是否是数据库中存在的正确_id 。如果它们不存在或错误,则响应将包含空数组甚至返回错误。

例如,当错误发生时,我在开始时添加了这个,但那些 _ids 不存在(我之前删除了它们但忘记了)首先在我的 orderLines 集合中(如果它们存在,您仍然可以添加不存在的 _ids正确的 _id 结构,所以要注意)

POST http://localhost:5000/api/v1/orders/62326179b9c85d3fc833d686
Content-Type: application/json

{
  "orderedlines":[
      {"_id": "6251be4d4186c34788e4f034"},
      {"_id": "6251be494186c34788e4f030"}
  ],
  "totalPrice":"121.99"
}

第三。如果您使用的是 TypeScript,则可以使用三种方法:

  1. 使用自己的类型
export type OrderLine = {
  _id: string
}

export type OrderDocument = Document & {
  userId: string
  orderedlines: OrderLine[],
  totalPrice: number
}
  1. 说这将是一个字符串数组
export type OrderDocument = Document & {
  userId: string
  orderedlines: string[],
  totalPrice: number
}
  1. ObjectId 数组
export type OrderDocument = Document & {
  userId: string
  orderedlines: mongoose.Schema.Types.ObjectId[]
  totalPrice: number
}

在考虑了以上所有三件事之后,最终对我有用的是这种方法:

const findOrdersForUserId = async (
  userId: string
): Promise<OrderDocument[]> => {
  const ordersToReturn = await Order.find({ userId: userId })
    .sort({ _id: 1 })
    .populate('userId')
    .populate({
      path: 'orderedlines',
      populate: { path: 'productId', model: 'Product' },
    })
  return ordersToReturn
}

这是我得到的响应的一部分,只是为了展示orderedline、productId和userId都被正确填充

{
        "quantity": 4, //part of a single orderedline object
        "_id": "6251be494186c34788e4f030", //part of a single orderedline object
        "productId": { // beginning of populated productId
          "_id": "623b3b24da0e7828602c78e3",
          "name": "AMY SS14R - TRICKSTER",
          "image": "https://res.cloudinary.com/dtggdx3hc/image/upload/v1648048425/amy-deluxe-stick-steel-r-ss09r10_1000x1000_bfngtl.jpg",
          "price": 1299,
          "__v": 0
        }, // end of populated productId
        "price": 2.99, //part of a single orderedline object
        "__v": 0 //part of a single orderedline object
      }
    ], // end of the orderedline array of objects
    "_id": "6252bfa8dd00081d7c273e4d", // _id of the order
    "userId": { //beginning of populated userId
      "favourites": [
        "623b39e684b9baf1109053f8",
        "623b3afada0e7828602c78df",
        "623b3b49da0e7828602c78e7",
        "623b39ba84b9baf1109053f7",
        "623b3b59da0e7828602c78e9"
      ],

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章