【问题标题】:Issue Trying to Save an Array of Object Ids Mongoose尝试保存对象 ID 数组的问题 Mongoose
【发布时间】:2022-01-15 17:04:06
【问题描述】:

我正在使用mongooseexpress 分别创建我的数据库和服务器。

我的数据有如下架构:

const mongoose = require('mongoose')
const {Schema} = mongoose

const quotesSchema = new Schema({
  tags: [
    {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Tags' // I want to save an array of tags coming in from the request body
     }
   ],
  content: {
     type: String,
     required: true
  },
  author: {
     type: String,
     required: true
  },
  authorSlug: {
     type: String,
  },
  dateAdded: {
     type: Date,
     default: Date.now()
  },
   dateModified: {
      type: Date,
      default: Date.now()
   },
})

const Quotes = new mongoose.model('Quotes', quotesSchema)
module.exports = Quotes

我想保存来自请求正文的一组标签,但它只保存数组中的一项。

这是我的示例代码:

router.post('/', async (req, res, next) => {
try {
    const {tags, author, content} = req.body
    const slug = author.replace(/\s+/g, '-').toLowerCase()

    var tagIds = []
    
    tags.forEach( async (tag) => {
        const foundTag = await Tag.find({name: tag}) // I first of all search my tag collection 
 // to see if the names supplied in the request body tags array exist, 
 // then try to extract their Objectids and store in an array to move to the next step - saving the quote

        // foundTag.forEach(async (item) => {
        //     return await tagIds.push(item._id)
        // })            

        for (var i = 0; i < foundTag.length; i++) {
            tagIds.push[i]
        }

        console.log(tagIds)
        
        const quote = new Quote({
            tags: tagIds,
            content,
            author,
            authorSlug: slug
        })

        const quoteToSave = await quote.save()

        return res.status(201).json({
            success: true,
            msg: 'Quote Created Successfully',
            quote: quoteToSave
        })

     })
  } catch (error) {
     console.error(error)
  }
})

如何将完整的标签数组作为参数传递给要保存的报价。我认为这里的问题是它没有等待第二个标签进入数组。

这是我在 Postman 中的请求-响应图像:

如何从req.body 获取数组标签并将其保存为我的报价对象的一部分?目前,我正在我的forEach 循环中做所有事情,这对我来说似乎不够体面。有没有最好的方法,比如等待数据,然后保存部分不会有任何父控制语句,就像目前一样。

谢谢

【问题讨论】:

    标签: node.js arrays express mongoose objectid


    【解决方案1】:

    #1如果您将在forEach 中使用async functions,则将Promise.all()bluebird 一起使用。

    #2 MongoDB operators 非常有用。

    #3了解forEachmap之间的区别非常重要。

    #4如果使用正确,express response不需要return声明。


    最终代码如下所示:

    router.post('/', async (req, res, next) => {
    
        const { tags, author, content } = req.body
        const slug = author.replace(/\s+/g, '-').toLowerCase()
    
        var foundTags = await Tag.find({ name: { $in: tags } })
    
        if (foundTags) {
    
            var tagsIds = []
            foundTags.map(tag => {
                tagsIds.push(tag._id);
            })
    
            const quote = new Quote({
                tags: tagsIds,
                content,
                author,
                authorSlug: slug
            })
    
            const quoteToSave = await quote.save()
    
            if (quoteToSave) {
                res.status(201).json({
                    success: true,
                    msg: 'Quote Created Successfully',
                    quote: quoteToSave
                })
            } else {
                res.status(500).json("failed saving quote")
            }
        } else {
            res.status(500).json("failed finding tags")
        }
    })
    

    【讨论】:

    • 兄弟,这非常有效。你能解释一下运算符中的用例吗?它似乎对我有好处,所以我可以采用它。此外,标签和报价是捆绑在一起的。我想要一个场景,如果我创建一个带有标签名称的报价,该标签将更新它的报价计数。我要分享一个sn-p吗?谢谢
    • 很高兴它成功了,MongoDB operators 有据可查,还有大量关于它们的文章、比较和用例。
    • 我愿意在这种情况下为您提供帮助,但是在您尝试解决它之后,如果您遇到困难并且在这里找不到任何以前的问题,我会尽力为您提供帮助。
    • 谢谢。一直在阅读运营商。
    • 让我再试一次。我很可能会问另一个问题并在此处分享链接。这行得通吗?
    猜你喜欢
    • 1970-01-01
    • 2019-03-05
    • 2020-09-01
    • 1970-01-01
    • 2016-04-23
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多