【问题标题】:Saving an array of objects to db Nodejs and MongoDB将对象数组保存到 db Nodejs 和 MongoDB
【发布时间】:2020-03-05 18:04:29
【问题描述】:

我对 Nodejs 和 MongoDB 还很陌生。

所以我在 Nodejs 中构建了一个如下所示的模式(如下所示) - 数据模式

// create Data Schema
const dataSchema = new mongoose.Schema({
    allItems: {
        // store all expenses here
        exp: [{
            description: { type: String, require: true, min: 2, max: 50 },
            value: { type: Number, require: true },
            percentage: { type: Number, require: true }
        }],
        // store all incomes here
        inc: [{
            description: { type: String, require: true, min: 2, max: 50 },
            value: { type: Number, require: true }
        }]
    },
    // store total incomes & expenses
    totals: {
        // sum of total expenses, init = 0
        exp: { type: Number, require: true, default: 0},
        // sum of total incomes, init = 0
        inc: { type: Number, require: true, default: 0}
    },
    // store total budgets, init = 0
    budget: { type: Number, require: true, default: 0 },
    // store percentage of total budget
    // init -1 = something is not in existance yet
    percentage: { type: Number, require: true, default: -1 } 
})

并且有一个post router保存新数据到db(如下图

router.post('/', async (req, res) => {

    // hold exp & inc array length
    expLength = req.body.allItems.exp.length
    incLength = req.body.allItems.inc.length

    // do something to hold allItems exp & inc data first
    // do some code here?

    // create new data
    const data = new Data({
        allItems: {
            exp: [
                {
                    description: req.body.allItems.exp,
                    value: req.body.allItems.exp,
                    percentage: req.body.allItems.exp
                }
            ],
            inc: [
                {
                    description: req.body.allItems.inc,
                    value: req.body.allItems.inc
                }
            ]
        },
        totals: {
            exp: req.body.totals.exp,
            inc: req.body.totals.inc
        },
        budget: req.body.budget,
        percentage: req.body.percentage
    })

    try {
        const saveData = await data.save()
        res.json(saveData)
    } catch(err) {
        res.json({
            message: err
        })
    }
})

所以我使用 Postman 来帮助我了解 nodejs 和 mongodb。

在邮递员中,我准备好执行这些数据(如下所示)。在哪里,我在 allItems 下的数组 exp 中有 2 个对象。

{
    "allItems": {
        "exp": [
            // first object
            {
                "description": "Rent",
                "value": 500,
                "percentage": 50
            },
            // second object
            {
                "description": "Loan",
                "value": 250,
                "percentage": 25
            }
        ],
        "inc": [
            {
                "description": "Web",
                "value": 1000
            }
        ]
    },
    "totals": {
        "exp": 750,
        "inc": 1000
    },
    "budget": 250,
    "percentage": 75
}

但不幸的是它只能保存1个对象,这是第一个,因为我在post router中将数组设置为'0'如下图) .

{
    "totals": {
        "exp": 750,
        "inc": 1000
    },
    "budget": 250,
    "percentage": 75,
    "_id": "5e6139b3111a7b593ce296cd",
    "allItems": {
        "exp": [
            // only save the first object
            {
                "_id": "5e6139b3111a7b593ce296ce",
                "description": "Rent",
                "value": 500,
                "percentage": 50
            }
        ],
        "inc": [
            {
                "_id": "5e6139b3111a7b593ce296cf",
                "description": "Web",
                "value": 1000
            }
        ]
    },
    "__v": 0
}

我认为我应该首先执行 for 循环 或其他操作来存储 inc & exp 数据数组。但我就是不知道怎么做。

我一直在通过谷歌搜索它。但是还没有运气。无论如何,任何帮助将不胜感激。谢谢。

顺便说一句,它给了我这个错误(如下图) -

"_message": "Data validation failed",
"message": "Data validation failed: allItems.exp.0.description: Cast to String failed for value \"[\n  { description: 'Rent', value: 500, percentage: 50 },\n  { description: 'Loan', value: 250, percentage: 25 }\n]\" at path \"description\", allItems.exp.0.value: Cast to Number failed for value \"[\n  { description: 'Rent', value: 500, percentage: 50 },\n  { description: 'Loan', value: 250, percentage: 25 }\n]\" at path \"value\", allItems.exp.0.percentage: Cast to Number failed for value \"[\n  { description: 'Rent', value: 500, percentage: 50 },\n  { description: 'Loan', value: 250, percentage: 25 }\n]\" at path \"percentage\", allItems.inc.0.description: Cast to String failed for value \"[ { description: 'Web', value: 1000 } ]\" at path \"description\", allItems.inc.0.value: Cast to Number failed for value \"[ { description: 'Web', value: 1000 } ]\" at path \"value\"",
"name": "ValidationError"

【问题讨论】:

    标签: node.js mongodb mongoose save arrayobject


    【解决方案1】:

    您可以在 req.body.allItems.exp 上放置一个 forEach 循环,并准备要保存在 exp 中的 expArr 数组:

    var expArr = [];
    req.body.allItems.exp.forEach(function(eachObj){
       var obj = {
          "description": eachObj.description,
          "value": eachObj.value,
          "percentage": eachObj.percentage
       }
       expArr.push(obj);
    });
    

    虽然,通过查看您的代码,似乎不需要任何循环,您可以像这样直接保存 exp 数据:

    router.post('/', async (req, res) => {
    
    // hold exp & inc array length
    expLength = req.body.allItems.exp.length
    incLength = req.body.allItems.inc.length
    
    // do something to hold allItems exp & inc data first
    // do some code here?
    
    // create new data
    const data = new Data({
        allItems: {
            exp: req.body.allItems.exp,
            inc: req.body.allItems.inc
        },
        totals: {
            exp: req.body.totals.exp,
            inc: req.body.totals.inc
        },
        budget: req.body.budget,
        percentage: req.body.percentage
    })
    
    try {
        const saveData = await data.save()
        res.json(saveData)
    } catch(err) {
        res.json({
            message: err
        })
     }
    })
    

    【讨论】:

    • 它给出了message: Data validation failed 的错误。我已经更新了我上面的问题。请看一看。如何忽略验证?
    • @lala 请仔细阅读我的回答。我将“req.body.allItems.exp”直接分配给“allItems”中的“exp”。您将“req.body.allItems.exp”分配给“描述”、“价值”和“百分比”。请用我的“const data”部分替换您的“const data”部分代码。它会起作用的。
    • 对不起!我的错。无论如何,有什么特别的原因我不必在exp & inc 中指定key&value 数据对。我不知道它可以这样工作。直到你给我看。
    • 这取决于“req.body”中的值如何,如果与schema格式相同,则不需要在添加到DB之前再次处理。
    • 哦,很高兴知道!无论如何,感谢您的帮助!欣赏!
    猜你喜欢
    • 2017-02-13
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 2017-10-21
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多