13

現在、次のデータセットがあります。

{  
    'component_id':1,  
    '_locales':[   
        {  
            'url': 'dutch',  
            'locale': 'nl_NL'  
        } 
    ] (etc)
}

行をロケールで更新したい場合は、次のようなものを実行します。

db.components.update(
    {'component_id': 1, '_locales.locale': 'nl_NL'},
    {$set: {'_locales.$': {'url': 'new url','locale':'nl_NL'}}, 
    true
);

これは、ロケールが存在しなくなるまで正常に機能します。

db.components.update(
    {'component_id': 1, '_locales.locale': 'en_US'},
    {$set: {'_locales.$': {'url': 'new url','locale':'en_US'}}, 
    true
);

component_id には一意のインデックスがあるため、重複キーに関する例外がスローされます。

新しい「ドキュメント」を別のロケールで自動的に追加し、既に存在する場合は更新する方法はありますか? ドキュメントによると、位置演算子を使用すると、「アップサート」では機能しません。

4

1 に答える 1

12

$ addToSetを使用して、重複する配列要素がないことを確認してセットに追加できますが、これは「更新」の場合には機能しません。

やりたいことをするためには、データ構造を次のように変更する必要があります。

{
    "_id" : ObjectId("4f9519d6684c8b1c9e72e367"),
    "component_id" : 1,
    "_locales" : {
        "nl_NL" : {
            "url" : "dutch"
        }
    }
}

これで、nl_NLロケールを次のように更新できます。

db.components.update( { component_id: 1 }, { $set: { '_locales.nl_NL.url' : 'new url' } }, true );

また、次のような新しいロケールも機能します。

db.components.update( { component_id: 1 }, { $set: { '_locales.en_US.url' : 'American' } }, true );

次のように、ネストされたオブジェクトの一部としてロケールを使用することも検討してください。

{
    "_id" : ObjectId("4f9519d6684c8b1c9e72e367"),
    "component_id" : 1,
    "_locales" : {
        "nl_NL" : {
            "url" : "dutch"
            "locale" : "nl_NL"                 
        }
    }
}

これにより、場合によってはデータの取得が容易になります。

于 2012-04-23T09:11:43.687 に答える