无法使用mongoose在mongo中持久保存对象数组

时间:2015-08-10 13:59:18

标签: node.js mongodb express mongoose

我正在尝试使用mongoose在文档中保留一组对象。我已经尝试了多次,但它不是在文档中持久化数组。它在文档中放置一个空数组。

以下是我的架构:

var ProfileSchema = new Schema({

  name: String,
  PagesData: [{
    pageAccessToken: {type: String, get: decryptText, set: encryptText},
    category: String,
    name: String,
    id: String,
    perms: [String]
  }]

});

module.exports = mongoose.model('Profile', ProfileSchema);

我正在尝试使用以下查询保存包含对象数组的文档:

var newProfile = new Profile();
newProfile.name = "someName";
newProfile.PagesData = [ { pageAccessToken: 'someToken',
    category: 'Bags/Luggage',
    name: 'someBrandName',
    id: '12345',
    perms: 
     [ 'ADMINISTER',
       'EDIT_PROFILE',
       'CREATE_CONTENT' ] } ];

newProfile.save(function(err, result, numAffected){
    if(err) {
        console.log(err);
        res.send(500, "Error");
    }
    console.log(result);
    res.send(200, "Success");
});

我尝试使用

调试mongo命令
  

require('mongoose')。set('debug',true)

在调试日志中显示,在插入命令执行期间显示空数组。

任何人都可以告诉我如何在我的架构中存储这个对象数组?

谢谢,

更新

已经太久了,我仍然无法找出问题的根本原因。为此,github上有一个很长的线程。 https://github.com/Automattic/mongoose/issues/3249 我希望其他专家请看一下,并建议我以某种方式解决问题。我真的很困惑。

更新2:

到目前为止,这些解决方案都没有对我有用,因此我决定仅修改架构以满足我的要求。这导致了一个不同的问题:

我想创建一个地图,其中objectId为键,字符串值数组为其值。我能得到的最接近的是:

var schema = new Schema({
   map: [{myId: {type:mongoose.Schema.Types.ObjectId, ref: 'MyOtherCollection'}, values: [String]}]
});

但不知怎的,这对我不起作用。当我使用{upsert:true}执行更新时,它无法正确填充地图中的键:值。事实上,我甚至不确定我是否正确地声明了架构。

有人能告诉我架构是否正确?另外,如何为此架构使用{upsert:true}执行更新?

此外,如果上述情况不正确且无法实现,那么我该如何通过其他方式对我的需求进行建模。我的用例是我想保留给定objectId的值列表。我不希望任何带有相同键的重复条目,这就是选择地图的原因。

请说明方法是否正确或是否应以其他方式建模?

由于

4 个答案:

答案 0 :(得分:8)

我尝试了您在此处提供的确切代码,并且它为我工作。我不确定是什么原因导致了这个问题。除非我们得到同样的问题,否则很难纠正它。 以下是您可能尝试的一些建议:

  1. 创建一个简单的架构并尝试以这种方式存储对象 如果它必须对模式做一些事情,请弄明白。
  2. 您可以在示例应用中试用您的架构,以查找是否有一些 依赖导致问题。
  3. 一旦你知道问题究竟在哪里,你就能找到解决方案。我希望它有所帮助。

答案 1 :(得分:5)

我测试了这个并且插件适用于我使用以下: (我必须删除get:decryptText,set:encryptText)

var n = { name: "Testing for mongoose", PagesData : [{ pageAccessToken: 'someToken',
    category: 'Bags/Luggage',
    name: 'someBrandName',
    id: '12345',
    perms: 
     [ 'ADMINISTER',
       'EDIT_PROFILE',
       'CREATE_CONTENT' ] } ] }



Profile.create(n, function (err) {
            if (!err) {

                return 'records saved successfully';
            }
            else {

                return error on save:' + err;
            }
        });

Screenshot from DB result:

答案 2 :(得分:3)

要创建多个pageDatas,您可以将其用作嵌入式集合,而不是使用数组。

架构如下:

var PagesDataSchema = new Scheme({

    pageAccessToken: {type: String, get: decryptText, set: encryptText},
    category: String,
    name: String,
    id: String,
    perms: [String]
})
var ProfileSchema = new Schema({

  name: String,
  PagesData: [PagesDataSchema]

});

module.exports = mongoose.model('Profile', ProfileSchema);

参考http://mongoosejs.com/docs/subdocs.html

保存您可以使用的文档。

exports.save = function(req,res){
var test = new ProfileSchema;  // new object for ProfileSchema domain.
test.name= req.body.name;
if(req.body.PagesData){
 req.body.PagesData.forEach(function(page){  // For every element of pageData from   client.
    test.PagesData.push(page)  // This pushes each and every pagedata given from the client into PagesData.
})
}
test.save(function (saveErr, saved) {  // Saves the new document into db.
if (saveErr) {
    console.log(saveErr)
    return;
}
res.status(HttpStatus.OK).json(saved);
});
};

希望这有帮助。

答案 3 :(得分:0)

你试过吗

Profile.create({
  name: "someName",
  PagesData: [
    {
      pageAccessToken: 'someToken',
      category: 'Bags/Luggage',
      name: 'someBrandName',
      id: '12345',
      perms: [
        'ADMINISTER',
        'EDIT_PROFILE',
        'CREATE_CONTENT'
      ]
    }
  ]
}, function(err, profile) {
    // do your stuff
})