Пн goose поиск по параметрам, включая подмассив - PullRequest
0 голосов
/ 27 мая 2020

Я создаю приложение, в котором создается задание, и идентификатор этого задания добавляется в другую коллекцию (клиент), чтобы на задание можно было ссылаться из самого клиента. До сих пор мне удалось добавить идентификатор задания в коллекцию клиента, но мне сложно понять, как удалить идентификатор задания из коллекции клиента, если задание удалено. Это связано с тем, что идентификатор хранится как подколлекция внутри клиента. Код, который я пытаюсь заставить работать, приведен ниже:

// delete
app.delete("/jobs/:id", function(req, res){ 

            Client.find({jobs._id: req.params.id}, function (err, foundClient){  //This part doesn't work
                if (err) {
                    console.log(err);
                } else {
                    // Add id identifier to Client
                    foundClient.jobs.pull(req.params.id);
                    foundClient.save();
                }
            }); 
//  Delete Job
    Job.findByIdAndRemove(req.params.id, function(err, deletedJob){
        if (err){
            console.log(err)
        } else {            
            //  Redirect
            res.redirect("/jobs");
        }
    });
});

Я пытаюсь заставить работать logi c этой части:

Client.find({jobs._id: req.params.id}, 

Вот клиент Схема

// =======================Client Schema

var clientSchema = new mongoose.Schema({
    organization_name: String,
    first_name: String,
    middle_name: String,
    last_name: String,
    email_address: String,
    phone_number: String,
    street: String,
    city: String,
    state: String,
    zip: String,
    description: String,
    active: {type: Boolean, deafult: true},
    date_added: {type: Date, default: Date.now},
    transactions: [{type: mongoose.Schema.Types.ObjectID, ref: "Transaction"}],
    jobs: [{type: mongoose.Schema.Types.ObjectID, ref: "Job"}]
});

module.exports = mongoose.model("Client", clientSchema);

По сути, то, что я пытаюсь сказать ему, это найти клиента, у которого массив заданий клиента содержит идентификатор, равный идентификатору удаляемого задания. Конечно, этот синтаксис неверен, поэтому он не работает. Мне не удалось найти документацию, объясняющую, как я могу это сделать. Есть ли более простой способ сделать это, как я пишу здесь? Я знаю, что могу запросить БД таким образом, если само задание не было массивом и содержало только одну сингулярную переменную. Есть ли способ сделать это или мне нужно написать полностью отдельную функцию цикла, чтобы это работало? Спасибо.

1 Ответ

1 голос
/ 27 мая 2020

jobs - это массив идентификаторов, поэтому, чтобы найти некоторые документы в коллекции Client, которые имеют req.params.id в массиве jobs, запрос должен быть примерно таким

Client.find({jobs: req.params.id})

, это вернет массив документы, каждый документ имеет массив идентификаторов заданий

Если вы уверены, что req.params.id существует только в одном документе, вы можете использовать findOne вместо find, и это вернет только один документ с массив идентификаторов заданий

это касается find части

в отношении идентификатора удаления задания из массива заданий, мы можем использовать один из следующих методов

1- как вы предложили, мы можем сначала найти документы клиентов, которые имеют этот идентификатор задания, а затем удалить этот идентификатор из всех массивов заданий во всех соответствующих документах

вот так

Client.find({ jobs: req.params.id }, async function (err, foundClients) {
    if (err) {
        console.log(err);
    } else {
        // loop over the foundClients array then update the jobs array

        for (let i = 0; i < foundClients.length; i++) {
            // filter the jobs array in each client 

            foundClients[i].jobs = foundClients[i].jobs || []; // double check the jobs array

            foundClients[i].jobs = foundClients[i].jobs.filter(jobId => jobId.toString() !== req.params.id.toString());
            // return all the jobs Ids that not equal to req.params.id
            // convert both jobId and req.params.id to string for full matching (type and value)

            await foundClients[i].save(); // save the document
        }

    }
});

2 - мы можем использовать оператор обновления массива $ pull , чтобы напрямую обновить массив заданий

что-то вроде этого

Client.updateMany(
    { jobs: req.params.id }, // filter part
    {
        $pull: { jobs: { $in: [req.params.id] } } // update part
    },
    function (err) {
        if (err) {
            console.log(err);
        } else {
            console.log('job id removed from client documents successfully');
        }
    }
);

надеюсь, что это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...