var fruitSchema = new schema ({
fruitName: {type: String},
priceArray: {type: Array}
});Fruit.findOneAndUpdate({fruitName: req.body.fruitName},
{
$push: {
priceArray: {
price: req.body.price,
description: req.body.description
}
}
} <form method="POST" action="/fruit">
<div class='form-group'>
<label for="fruitName">Fruit Name</label>
<input type="text" name="fruitName" id="fruitName"/>
</div>
<div>
<label for="price0">Price</label>
<input type="text" name="price[0]" id="price0"/>
<label for="description0">Description</label>
<input type="text" name="description[0]" id="description0"/>
</div>
<div>
<label for="price1">Price</label>
<input type="text" name="price[1]" id="price1"/>
<label for="description1">Description</label>
<input type="text" name="description[1]" id="description1"/>
</div>
<input type="submit" value="submit">
</form> {
"fruitName" : "test fruit",
"priceArray" : [
{
"price" : [
"$2.00",
"$3.00"
],
"description" : [
"Good",
"Bad"
]
}
{
"fruitName" : "test fruit",
"priceArray" : [
{
"price" : "$2.00"
"description: "Good"
}
{
"price" : "$3.00"
"description" : "Bad"
}
]
}Hi,
My array in my MongoDB is not being structured the way I want it to be. I am using node.js, Express, and Mongoose
There are two issues with your code. First is the form:
<input type="text" name="price[0]" id="price0"/>
<input type="text" name="description[0]" id="description0"/>
<input type="text" name="price[1]" id="price1"/>
<input type="text" name="description[1]" id="description1"/>
this form will create an array like you’ve seen, e.g. {price:[price0, price1], description:[description0, description1]}. If you want to create paired {priceArray: [{price:..., description:...},...]} array of objects instead, the form would have to be modified to reflect the structure you want. For example:
<input type="text" name="priceArray[0][price]" id="price0"/>
<input type="text" name="priceArray[0][description]" id="description0"/>
<input type="text" name="priceArray[1][price]" id="price1"/>
<input type="text" name="priceArray[1][description]" id="description1"/>
note the content of the name attributes to reflect the output structure you want.
The second issue is the Mongoose code that pushes new priceArray items:
Fruit.findOneAndUpdate({fruitName: req.body.fruitName},
{
$push: {
priceArray: {
price: req.body.price,
description: req.body.description
}
}
}
in this form, it will push the new array into an array. When you attempt to add to an existing fruitName, the resulting document will look like:
{
"fruitName": "q",
"priceArray": [
[ {"description": "1", "price": "1"}, {"description": "1", "price": "1"} ],
[ {"description": "2", "price": "2"}, {"description": "2", "price": "2"} ]
],
}
which is probably not what you have in mind (array within another array). If you’re using MongoDB 2.4 and above, you can use the $each operator, e.g.:
Fruit.findOneAndUpdate(
{fruitName: req.body.fruitName},
{$push: {priceArray: {$each: req.body.priceArray}}},
{upsert:true, new:true},
function(err,fruit) {
if (err) return console.error(err)
console.log(fruit)
}
)
which will result in:
{
"fruitName": "q",
"priceArray": [
{"description": "1", "price": "1"},
{"description": "1", "price": "1"},
{"description": "2", "price": "2"},
{"description": "2", "price": "2"}
],
}
The above snippets were tested with MongoDB 3.2.7, Mongoose 4.5.3, and Express 4.14.
Best regards,
Kevin