Сохранение массива объектов в db Nodejs и MongoDB - PullRequest
1 голос
/ 05 марта 2020

Я довольно новичок в 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 } 
})

и имеет пост маршрутизатор до сохранить новые данные в дБ (, как показано ниже )

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
        })
    }
})

Поэтому я использую Почтальон , чтобы помочь мне узнать о nodejs и mongodb.

В Почтальоне у меня есть эти данные (, как показано ниже ) готов к исполнению. Где, у меня есть 2 объекта в массиве exp в allItems .

{
    "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 объект, который является первый, так как я установил массив равным '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
}

Я думаю, что я должен сделать для l oop или что-то для хранения массива в c & exp данных в первую очередь. Но я просто не знаю, как.

Я искал его через Google. Но пока не получилось. В любом случае, любая помощь будет оценена. Спасибо.

Кстати, это дало мне эту ошибку (, как показано ниже ) -

"_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"

1 Ответ

1 голос
/ 05 марта 2020

Вы можете поместить forEach l oop в req.body.allItems.exp и подготовить массив expArr для сохранения в exp :

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

Хотя, глядя на ваш код, кажется, что никакой l oop не нужно, вы можете просто сохранить данные 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
    })
 }
})
...