Mongoose обновляет несколько вложенных документов - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь обновить один вложенный документ addresses (работает), а затем обновить многие вложенные документы, кроме предыдущего.Обычно каждый раз, когда address меняет is_preferred на true, он должен обновлять предыдущий адрес, который is_preferred был true, до false (я пытаюсь обновить всех, кроме адреса, который изменился на true).

Пользовательский документ

_id: ObjectId("5b996f0fd5fbf511709f668f");
addresses: [
  {
    _id: ObjectId("5ba33e0991cd7a3bb85dab7e");
    is_preferred:true
  },
  {
    _id: ObjectId("5ba3e9337310c637207b44cb");
    is_preferred:false
  }
]

Вот мое решение:

// model
User = mongoose.model('user', new Schema({
    _id: { type: mongoose.Schema.Types.ObjectId, required: true },
    addresses: [
        {
            _id: { type: mongoose.Schema.Types.ObjectId, required: true },
            is_preferred: { type: Boolean, required: true }
        }
    ],
}, { collection: 'user' }););

// route
router.put('/updateAddress/:addressId', auth, user.updateAddress);

// user.js
exports.updateAddress = wrap(async(req, res, next) => {
    // update one object address `is_preferred` to true and return an array 'addresses' containing it
    const user = await User.findOneAndUpdate(
        { addresses: { $elemMatch: { _id: mongoose.Types.ObjectId(req.params.addressId) } } }, { 'addresses.$': req.body },
        { projection: { 
            addresses: { 
                $elemMatch: { _id: mongoose.Types.ObjectId(req.params.addressId) }
            }
        }, new: true }).lean();
    if (user) {
        // updated object `is_preferred` changed to true, so another objects must be false
        if (user.addresses[0].is_preferred) {
            // doesnt work
            await User.update({ _id: { $ne: mongoose.Types.ObjectId(req.params.addressId) }, is_preferred: true },
                { $set: { addresses: { is_preferred: false } } }, { multi: true });
        }
        res.status(200).json({success: true, message: 'Saved.', new_object: user.addresses[0]});
    } else {
        res.status(400).json({success: false, message: 'Error.'});
    }
});

Я могу обновить поддокумент user addresses is_preferred до true.Однако обновление другого addresses is_preferred до false не работает.Что я делаю неправильно?

1 Ответ

0 голосов
/ 21 сентября 2018

Я бы порекомендовал для сценария, подобного вашему, использовать промежуточное ПО mongoose pre или post ловушки схемы.Идея состоит в том, что вместо того, чтобы заниматься этим в вашем контроллере, вы бы позаботились об этом в своей схеме через это промежуточное программное обеспечение.

Единственное неудобство в том, что хуки pre и post не срабатывают findOneAndUpdate и вам нужно будет сначала сделать find, а затем update.

. Таким образом, вы должны сделать что-то подобное для ловушки post:

User.post('save', doc => {
  // You can update all the rest of the addresses here.
});

Также для вашего обновлениядля работы нужно сделать что-то вроде этого:

User.update(
   { "addresses._id": { $ne: mongoose.Types.ObjectId(req.params.addressId) }}, 
   { $set: { 'addresses.0.is_preferred': false }}, 
   { multi: true }
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...