Пн goose удалить объекты из массива объектов по некоторому фильтру - PullRequest
0 голосов
/ 01 августа 2020

У меня есть такая схема:

var resortSchema = new mongoose.Schema ({
name: String,
price: String,
reviews: [
    {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Review"
    }
]});


var reviewSchema = new mongoose.Schema({
    rating: {
        // Setting the field type
        type: Number,
        // Defining min and max values
        min: 1,
        max: 5,
        // Adding validation to see if the entry is an integer
        validate: {
            // validator accepts a function definition which it uses for validation
            validator: Number.isInteger,
            message: "{VALUE} is not an integer value."
        }
    },
    // author id and username fields
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User"
        },
        username: String
    },
    // resort associated with the review
    resort: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Resort"
    }
});

В коде я заполнил массив обзоров в документе курортов, и я хочу удалить только некоторые c обзоры (на основе идентификатора автора) из массив resort.reviews. Что-то вроде:

resort.reviews.pull({"author.id": someSpecificUserID});
resort.save();

Но это не работает. Как мне это сделать?

РЕДАКТИРОВАТЬ: Я могу найти все отзывы по определенному c идентификатору пользователя, но я не знаю, как выполнить фильтрацию по курорту. Я пробовал это:

console.log("req.user._id: " + typeof req.user._id); // object
console.log("req.params.id: " + typeof req.params.id); // string
console.log("ObjectId: " + typeof mongoose.Types.ObjectId(req.params.id));

var resortObjectID = mongoose.Types.ObjectId(req.params.id);

// Get ids of reviews matching a particular author
const reviews = await Review.find({ "author.id": req.user._id, "resort": resortObjectID });
console.log("reviews: " + reviews);     // reviews is []. if I remove "resort": resortObjectID I do get all the reviews of that user in all resorts. But I need to filter to only one resort.

//Pass review ids to $pull     // I am not sure if this works yet
await Resort.updateOne(
    { _id: req.params.id },
    { $pull: { reviews: { $in: reviews.map(x=>x._id) } } },
    { multi: true })

1 Ответ

0 голосов
/ 01 августа 2020

Поскольку обе коллекции (resort and review) различны, извлечение значения из одной коллекции на основе значений других коллекций просто не сработает. Поэтому сначала вам нужно будет получить идентификаторы отзывов, которые вы хотите удалить из коллекции review, а затем передать их в $pull

 1. Get ids of reviews matching a particular author
    
    const reviews = await db.review.find({"author.id": <someSpecificUserID>}, {_id: 1});

 2. Pass review ids to $pull

    await db.resort.update(
    { },
    { $pull: { reviews: { $in: reviews.map(x=>x._id) } } },
    { multi: true })
  
...