【问题标题】:Sails and subdocument ObjectId()Sails 和子文档 ObjectId()
【发布时间】:2016-05-03 06:09:55
【问题描述】:

我有一个现有的 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 并且没有嵌套模式,这似乎是另一个死胡同。

有没有什么办法可以解决这个问题,而无需在返回之前遍历整个集合,不必迁移数据库、更改文档或不必对数据库进行规范化?此数据由多个应用程序访问,需要保持原样。

【问题讨论】:

  • 顺便说一句,使用 .native() 进行搜索,确实会按预期返回 ID,但是如果我必须使用 .native() 进行简单查找,那么使用 Waterline 有什么意义?.使用其他一些实际上是为 MongoDB 设计的 ORM 会不会更好,例如 Mongoose?

标签: mongodb objectid subdocument


【解决方案1】:

可能有更好的方法来做到这一点,但最后我决定对返回的 JSON 进行递归迭代,将 ID 替换为适当的 ObjectID,这要感谢 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           
    }
  }

}

这个问题听起来像是一个水线错误,所以打开一个问题。希望这同时对其他人有所帮助。

【讨论】:

  • 能否提供该问题的链接?我想知道这是怎么回事!
猜你喜欢
  • 2014-09-11
  • 2018-06-11
  • 2023-03-11
  • 2014-07-01
  • 2014-11-09
  • 2014-10-11
  • 2020-12-26
  • 2020-05-22
  • 2018-06-24
相关资源
最近更新 更多