Sails和子文档ObjectId()

时间:2016-01-26 15:46:47

标签: mongodb objectid subdocument

我有一个现有的MongoDB集合,基本上看起来像:

users: [
{
    "_id": ObjectId("56a6f714a2c56f1c3b0f17f1"),
    "name": "Daniel",
    "phones" : [
        {
            "_id": ObjectId(""56a78dd1879c40ea63822141"),
            "areacode": 333,
            "number": 111111111
        },
        {
            "_id": ObjectId(""56a78dd1879c40ea63822141"),
            "areacode": 111,
            "number": 99999999
        }

    ]

},
{
    "_id": ObjectId("56a6f714a2c56f1c3b0f17f1"),
    "name": "John",
    "phones" : [
        {
            "_id": ObjectId(""56a78dd1879c40ea63822141"),
            "areacode": 333,
            "number": 111111111
        },
        {
            "_id": ObjectId(""56a78dd1879c40ea63822141"),
            "areacode": 111,
            "number": 99999999
        }
    ]

}
]

如您所见,我在子文档中使用对象ID将此数据与外部集合相关联,我们在这些集合中存储有关数字的其他信息。所有这些ID都是由Mongoose在其他应用程序中自动生成的,它会自动生成。

现在,在Waterline中,没有对子文档的模式支持,因此在对集合执行find()时,子文档ObjectId将作为JSON而不是ID字符串返回。

结果类似于

results: [
{
    "id": "56a6f714a2c56f1c3b0f17f1",
    "name": "Daniel",
    "phones" : [
        {
            "_id": {
                "_bsontype": "ObjectID",
                "id": "V§zÐ\u0019}dÒÏ_"
             }
            "areacode": 333,
            "number": 111111111
        },
        {
            "_id": {
                "_bsontype": "ObjectID",
                "id": "V§zÐ\u0019}dÒÏ_"
             }
            "areacode": 111,
            "number": 99999999
        }

    ]

}
]

Mongoose优雅地处理这个问题,你总是可以在客户端使用那些id来执行相关查询,但是使用Waterline,没有嵌套模式,这似乎是另一个死胡同。

有没有办法在没有循环整个集合之前解决这个问题,然后再返回它,不得不迁移数据库,更改文档或者必须将数据库中的地狱标准化?这些数据可以通过多个应用程序访问,并且需要保持原样。

1 个答案:

答案 0 :(得分:1)

有一种更好的方法可以做到这一点,但最后我决定在返回的JSON上递归迭代,用适当的ObjectID替换ID,这要归功于bson-objectid库。

我基本上做的是在模型级别的toJSON函数上调用此方法:

// Recursively iterate over a JSON object
function replaceBSONIDs(object){

   var ObjectID = require("bson-objectid");

  for(var x in object){

    if(typeof object[x] == 'object') {
      replaceBSONIDs(object[x]);
    } else {

        // Perform the actual replace of the _id with an object ID
        if('_id' in object) {
            object.id = ObjectID(object._id.id);
            delete object._id           
    }
  }

}

这个问题听起来像是一个水线虫,所以打开一个问题。希望这可以帮助其他人。