4

我已经用猫鼬建立了一个用户模式,其中包含一个子文档“联系人”。子文档“联系人”是联系人对象的集合,其中包含实际联系人(对另一个用户对象的引用)和一些与“友谊”相关的数据。

在我的前端应用程序中,我现在可以通过在我的联系人列表中添加或删除用户来管理联系人。前端将这些更改保存为对服务器的 HTTP PUT 请求。

PUT 请求包含整个用户对象,它或多或少地替换了数据库上的用户对象。不幸的是,无法替换子文档集合。您只能推送新的或删除它们。

以下是模式:

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
    }

});

目前,我尝试通过删除所有联系人并在请求中添加联系人来替换联系人:

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

有人真的知道如何将这个子文档集合更新为请求中的状态吗?

4

2 回答 2

6

您可以使用 _underscore 库过滤(拒绝)要删除的对象

这是一个如何在没有 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;
    })

预期的结果应该是:

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

如果你知道id,那就更好了。

然后,您要做的就是通过执行以下操作清空您的子文档:

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

如果要替换整个 subdoc 数组,为什么不直接替换它们:

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

保存并完成。

希望那些对你有帮助。

只是一个提示,在 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();
于 2012-11-23T16:37:46.093 回答
0

有一种更好的方法findOneAndUpdate可以做到这一点。

首先,您为数组中的所有对象(将是您的子文档)创建 Mongoose 文档。然后你使用常规findOneAndUpdate并替换那里的子文档数组。例如:

const subDocumentsArray = argumentArray?.map((object) => new subDocumentModel(object));
const document = await documentModel.findOneAndUpdate(
        { _id: id },
        { subDocumentsArray },
      );
于 2021-08-25T08:28:03.200 回答