Mongoose удалить элемент массива в документе и сохранить

У меня есть массив в моем модельном документе. Я хотел бы удалить элементы в этом массиве на основе ключа, который я предоставляю, а затем обновить MongoDB. Это возможно?

Здесь моя попытка:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var favorite = new Schema({
    cn: String,
    favorites: Array
});

module.exports = mongoose.model('Favorite', favorite, 'favorite');

exports.deleteFavorite = function (req, res, next) {
    if (req.params.callback !== null) {
        res.contentType = 'application/javascript';
    }
    Favorite.find({cn: req.params.name}, function (error, docs) {
        var records = {'records': docs};
        if (error) {
            process.stderr.write(error);
        }
        docs[0]._doc.favorites.remove({uid: req.params.deleteUid});

        Favorite.save(function (error, docs) {
            var records = {'records': docs};
            if (error) {
                process.stderr.write(error);
            }
            res.send(records);

            return next();
        });
    });
};

Пока он находит документ, но удаляет и сохраняет работы.

Ответ 1

Вы также можете сделать обновление непосредственно в MongoDB без необходимости загружать документ и изменять его с помощью кода. Используйте операторы $pull или $pullAll для удаления элемента из массива:

Favorite.update( {cn: req.params.name}, { $pullAll: {uid: [req.params.deleteUid] } } )

http://docs.mongodb.org/manual/reference/operator/update/pullAll/

Ответ 2

Проверенный ответ работает, но официально в MongooseJS последней версии вы должны использовать pull.

doc.subdocs.push({ _id: 4815162342 }) // added
doc.subdocs.pull({ _id: 4815162342 }) // removed

https://mongoosejs.com/docs/api.html#mongoosearray_MongooseArray-pull

Я просто тоже это искал.

См Даниил ответ для правильного ответа. Намного лучше.

Ответ 3

Поскольку избранное - это массив, вам просто нужно соединить его и сохранить документ.

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var favorite = new Schema({
    cn: String,
    favorites: Array
});

module.exports = mongoose.model('Favorite', favorite);

exports.deleteFavorite = function (req, res, next) {
    if (req.params.callback !== null) {
        res.contentType = 'application/javascript';
    }
    // Changed to findOne instead of find to get a single document with the favorites.
    Favorite.findOne({cn: req.params.name}, function (error, doc) {
        if (error) {
            res.send(null, 500);
        } else if (doc) {
            var records = {'records': doc};
            // find the delete uid in the favorites array
            var idx = doc.favorites ? doc.favorites.indexOf(req.params.deleteUid) : -1;
            // is it valid?
            if (idx !== -1) {
                // remove it from the array.
                doc.favorites.splice(idx, 1);
                // save the doc
                doc.save(function(error) {
                    if (error) {
                        console.log(error);
                        res.send(null, 500);
                    } else {
                        // send the records
                        res.send(records);
                    }
                });
                // stop here, otherwise 404
                return;
            }
        }
        // send 404 not found
        res.send(null, 404);
    });
};

Ответ 4

Ответы выше показывают, как удалить массив, а вот как вытащить объект из массива.

Ссылка: https://docs.mongodb.com/manual/reference/operator/update/pull/

db.survey.update( // select your doc in moongo
    { }, // your query, usually match by _id
    { $pull: { results: { $elemMatch: { score: 8 , item: "B" } } } }, // item(s) to match from array you want to pull/remove
    { multi: true } // set this to true if you want to remove multiple elements.
)

Ответ 5

Это работает для меня и действительно очень полезно.

SubCategory.update({ _id: { $in:
        arrOfSubCategory.map(function (obj) {
            return mongoose.Types.ObjectId(obj);
        })
    } },
    {
        $pull: {
            coupon: couponId,
        }
    }, { multi: true }, function (err, numberAffected) {
        if(err) {
            return callback({
                error:err
            })
        }
    })
});

У меня есть модель, имя которой - SubCategory и я хочу удалить купон из этой категории. У меня есть массив категорий, поэтому я использовал arrOfSubCategory. Поэтому я получаю каждый массив объекта из этого массива с помощью функции map с помощью оператора $in операторе.

Ответ 6

keywords = [1,2,3,4];
doc.array.pull(1) //this remove one item from a array
doc.array.pull(...keywords) // this remove multiple items in a array

если вы хотите использовать ... вы должны называть 'use strict'; в верхней части вашего js файла; :)