3

基本的に次のような既存の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 によって自動的に生成されました。

現在、ウォーターラインでは、サブドキュメントのスキーマ サポートがないため、コレクションで find() を実行すると、サブドキュメントの ObjectId が ID 文字列ではなく JSON として返されます。

この結果、次のような結果になります

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 ではネストされたスキーマがないため、これは別の行き止まりのようです。

コレクションを返す前にコレクション全体をループしたり、データベースを移行したり、ドキュメントを変更したり、データベースを完全に正規化したりすることなく、これを解決する方法はありますか? このデータは複数のアプリからアクセスされるため、そのままにしておく必要があります。

4

1 に答える 1

1

これを行うにはおそらくもっと良い方法がありますが、最終的には、返された JSON を再帰的に反復し、bson-objectidライブラリのおかげで ID を適切な 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           
    }
  }

}

問題は喫水線のバグのように聞こえるので、問題を開きます。それまでの間、これが他の誰かに役立つことを願っています。

于 2016-01-26T17:53:37.910 に答える