Я пытаюсь обновить массив в документе, добавив объект, если он не существует, и заменив объект в массиве в противном случае. Но ничего ($ push, $ addToSet), кроме параметра $ set, ничего не делает, а $ set работает как ожидалось - перезаписывает весь массив. Моя схема мангуста:
var cartSchema = mongoose.Schema({
mail: String,
items: Array
});
Обработчик почтового запроса:
app.post('/addToCart', function(req, res) {
var request = req.body;
Cart.findOneAndUpdate({
"mail": request.mail
}, {
$addToSet: {
"items": request.item
}
}, {
upsert: true
},
function(err, result) {
console.log(result);
}
);
res.send(true);
});
Данные, которые я отправляю от клиента:
{
"mail":"[email protected]",
"item":{
"_id":"59da78db7e9e0433280578ec",
"manufacturer":"Schecter",
"referenceNo":"Daemon-412",
"type":"Gitare",
"image":"images/ba9727909d6c3c26412341907e7e12041507489988265.jpeg",
"__v":0,
"subcategories":[
"Elektricne"
]
}
}
РЕДАКТИРОВАТЬ:
Я также получаю этот журнал, когда я запускаю запрос "addToCart":
{ MongoError: The field 'items' must be an array but is of type object in
document {_id: ObjectId('5a19ae2884d236048c8c91e2')}
Сравнение в $ addToSet преуспело бы только в том случае, если существующий документ имеет те же самые поля и значения, и поля находятся в одном порядке. В противном случае оператор потерпит неудачу.
Поэтому в вашем случае request.item всегда должен быть точно таким же.
Я бы рекомендовал создать модель "item". Затем ваша схема корзины будет выглядеть так:
var cartSchema = mongoose.Schema({
mail: String,
items: [{
type: ObjectId,
ref: 'item',
}],
});
И пусть MongoDB определит, существует ли элемент.
это должно сработать, вам просто нужно реализовать функцию objectExits
которая проверяет, является ли элемент тем, который вы ищете:
Cart.findOne({ "mail": request.mail })
.exec()
.then(cart => {
var replaced = cart.items.some((item, i) => {
if (item._id == request.item._id)) {
cart.items[i] = request.item;
return true;
}
})
if (!replaced) {
cart.items.push(request.item);
}
cart.save();
return cart;
})
.catch(err => {
console.log(err)
});
item
?