简体   繁体   English

Mongoose:如何替换一组子文档?

[英]Mongoose: How do I replace an array of subdocuments?

I have set up a user schema with mongoose which contains a subdocument "contacts".我已经使用 mongoose 设置了一个用户架构,其中包含一个子文档“联系人”。 The subdocument "contacts" is a collection of contacts objects which contain the actual contact (reference to another user object) and some data which is related to the "friendship".子文档“联系人”是联系人对象的集合,其中包含实际联系人(引用另一个用户对象)和一些与“友谊”相关的数据。

In my front-end application I can now manage the contacts by adding or removing users to my contact list.在我的前端应用程序中,我现在可以通过在我的联系人列表中添加或删除用户来管理联系人。 The front-end saves these changes as HTTP PUT requests to the server.前端将这些更改保存为对服务器的 HTTP PUT 请求。

The PUT request contains the whole user object which more or less replaces the user object on the database. PUT 请求包含整个用户对象,它或多或少地替换了数据库上的用户对象。 Unfortunately it is not possible to replace subdocument collection.不幸的是,无法替换子文档集合。 You only can push new ones or remove them.您只能推送新的或删除它们。

Here are the schemas:以下是架构:

var UserSchema = new Mongoose.Schema({

    username: { 
        type: String, 
        index: { unique: true, sparse: true }, 
        required: true, lowercase: true, trim: true
    },

    email: {
        type: String,
        index: { unique: true, sparse: true }, 
        required: true, lowercase: true, trim: true
    },

    contacts: [ContactSchema]

});

var ContactSchema = new Mongoose.Schema({

    user: {
        ref: "User",
        type: Mongoose.Schema.ObjectId
    },

    isContact: {
        type: Boolean,
        default: true
    }

});

Currently I try to replace the contacts by removing all and adding the one in the request:目前,我尝试通过删除所有联系人并在请求中添加联系人来替换联系人:

app.put('/me', loadUser, function(req, res, next) {
    var user = req.user;

    req.user.contacts.forEach(function(contact) {
        req.body.contacts.forEach(function(contact) {
            contact.remove();
        });
    });

    req.body.contacts.forEach(function(contact) {
        req.user.contacts.push(contact);
    });

    user.save(function(err, user) {
        if (err) return next(err);
        res.send(200);
    });
});

Has somebody actually an better idea how I can update this subdocument collection to the state in the request?有人实际上更好地了解如何将此子文档集合更新为请求中的状态吗?

You can use the _underscore library to filter (reject) the object you want to remove 您可以使用_underscore库来过滤(拒绝)要删除的对象

Here an example how to remove something from an array without foreach. 这是一个如何在没有foreach的情况下从数组中删除内容的示例。

var _und = require('underscore');

var array = [{_id:1, title:'object one'}, {_id:2, title:'object two'}, {_id:3, title: 'object three' }]
    the_target = 'object two';
    new_array = _und.reject(array, function(item){
       return item.title === target;
    })

The expected result should be: 预期结果应该是:

=> [{_id:1, title:'object one'}, {_id:3, title:'object three'}]

If you know the id, even better. 如果你知道id,甚至更好。

All you have to do then is empty your subdocs by doing this: 所有你需要做的就是通过这样做清空你的subdocs:

var mytargetarray = [];
    mytargetarray.push(new_array);
    mytargetarray.save();

If you want to replace the whole subdoc array, why not just replacing them: 如果要替换整个子数组,为什么不直接替换它们:

req.user.contacts = [];
req.user.contacts.push(req.body.contacts);

save and done. 保存完成。

Hope that helps a bit. 希望有点帮助。

Just a hint, in mongodb you work with object arrays, you can simple replace every value: 只是一个提示,在mongodb中你使用对象数组,你可以简单地替换每个值:

// active data from database
user.name = 'test user';
// now just give the object a new value
user.name = 'new name';
// and save .. done
user.save();

there is a better way using findOneAndUpdate to do this.有一个更好的方法使用findOneAndUpdate来做到这一点。

First you create Mongoose Documents for all the objects in the array (which will be your subdocuments).首先,您为数组中的所有对象(这将是您的子文档)创建 Mongoose 文档。 Then you use regular findOneAndUpdate and replace the subdocument array there.然后使用常规findOneAndUpdate并替换那里的子文档数组。 So for example:例如:

const subDocumentsArray = argumentArray?.map((object) => new subDocumentModel(object));
const document = await documentModel.findOneAndUpdate(
        { _id: id },
        { subDocumentsArray },
      );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM