Mongoose: обновление массива в документе не работает

1

Я пытаюсь обновить массив в документе, добавив объект, если он не существует, и заменив объект в массиве в противном случае. Но ничего ($ 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')}
  • 0
    Каково содержание item ?
  • 0
    Объект JSON в нижней части исходного поста
Показать ещё 2 комментария
Теги:
express
mongoose

2 ответа

0

Сравнение в $ addToSet преуспело бы только в том случае, если существующий документ имеет те же самые поля и значения, и поля находятся в одном порядке. В противном случае оператор потерпит неудачу.

Поэтому в вашем случае request.item всегда должен быть точно таким же.

Я бы рекомендовал создать модель "item". Затем ваша схема корзины будет выглядеть так:

var cartSchema = mongoose.Schema({
   mail: String,
   items: [{
        type: ObjectId,
        ref: 'item',
    }],
});

И пусть MongoDB определит, существует ли элемент.

0

это должно сработать, вам просто нужно реализовать функцию 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)
    });

Ещё вопросы

Сообщество Overcoder
Наверх
Меню