通过包括子数组在内的参数进行Mongoose查找。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过包括子数组在内的参数进行Mongoose查找。相关的知识,希望对你有一定的参考价值。

我正在创建一个应用程序,在该应用程序中,创建了一个作业,并将该作业的 id 添加到另一个集合(客户端)中,这样就可以从客户端本身引用该作业。 到目前为止,我已经能够将该作业的id添加到客户端的集合中,但我很难理解如何在删除该作业时从客户端的集合中删除该作业的id。 这是因为id被存储在客户端的一个子集合中。 我想让它工作的代码如下。

// 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");
        }
    });
});

我试图让这部分的逻辑工作。

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);

基本上,我想告诉它做的是找到客户机的job数组中包含一个id等于被删除的job的id的客户机。 当然,这种语法是不正确的,所以它不能工作。 我一直找不到解释如何做到这一点的文档。 我在这里写出来的方法,有没有更直接的方法? 我知道,如果作业本身不是一个数组,只包含一个单变量,我可以用这种方式查询db。 有什么方法可以做到这一点,还是说我需要写一个完全独立的循环函数才能让这个工作正常进行? 谢谢您。

答案

jobs是一个id的数组,所以要在客户机集合中找到一些文档,这些文档有 req.params.id 在job数组中,查询的内容应该是这样的

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

这将返回一个文档数组,每个文档都有一个作业数组Ids。

如果你确定req.params.id只存在于一个文档中,你可以使用findOne来代替find,这将只返回一个文档中的job Ids数组。

这是关于 find 部分

关于从job数组中删除job Id,我们可以使用以下方法之一。

1-按照你的建议,我们可以先找到有这个工作ID的客户文档,然后从所有匹配文档中的所有工作数组中删除这个ID。

这样

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-我们可以使用 数组更新操作符,直接更新作业数组

这样

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');
        }
    }
);

希望对你有帮助

以上是关于通过包括子数组在内的参数进行Mongoose查找。的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mongoose 查找数组元素?

Mongoose 聚合内部查找按字段分组

通过 Mongoose、Node.js、MongodB 中的特定属性查找嵌入式文档

mongoose如何查找某个数组里含有某个值

使用 Typescript 在 Mongoose 中缺少子文档方法

使用 Typescript 在 Mongoose 中缺少子文档方法