1

次のような構造のドキュメントがあります。

{
    "_id" : 1000001,
    "ListMembers" : [
            {
                    "MemberID" : 1000,
                    "Notes" : "Test Notes for 1000"
            },
            {
                    "MemberID" : 1001,
                    "Notes" : "Test Notes for 1002"
            }
    ]

}

アプリケーションは一意の ID を生成します。私は以下を達成する必要があります:

  1. ドキュメントが存在しない場合は、配列フィールドを使用して新しいドキュメントを挿入します。
  2. ドキュメントがコレクションに存在し、メンバー レコードが配列に存在する場合は、メンバー ノートを更新します。
  3. ドキュメントがコレクションに存在し、メンバー レコードが配列に存在しない場合は、配列にメンバー レコードを挿入します。

ここで #1 と #2 は正常に機能しますが、上記の #3 では {upsert:true} オプションが機能しません。ドキュメントは存在するがメンバーレコードが存在しない場合、同じIDで新しいドキュメントを挿入しようとしますが、明らかに重複キーエラーが発生します。MongoDB はこのシナリオで UPSERT 操作をサポートしていますか、それともドキュメントの存在を確認してから、#1 と ($pull と $push) に対して INSERT を実行して、配列フィールドで #2 と #3 を達成する必要がありますか。

4

1 に答える 1

0

現在、$ 位置演算子はアップサートをサポートしていないため、これはサポートされていません。

アップサート操作で位置演算子 $ を使用しないでください。挿入すると、挿入されたドキュメントのフィールド名として $ が使用されるためです。

位置演算子は、メンバー レコードのメモを更新するために必要ですが、アップサートでは機能しません。

私がお勧めするロジックは、更新クエリを実行して #2 と #3 をカバーすることです。つまり、writeconcernが 1 であることを確認して、更新されたドキュメントの数を返します。何も返されない場合は、項目を $push するための挿入を行いますListMembers- これは #1* をカバーします

*ここには競合状態が発生する可能性があります - アスペクトと一致しないことを確認して writeconcern を設定するときに確認する必要がある余分なポイントがあり$pushます。操作が 0 を返す場合- これは、最初の操作とこの操作の間にドキュメントが更新されたことを意味します。したがって、一致するものがあり、更新されるため、元に戻ることができます。ListMembers$push$update

于 2013-01-31T11:14:44.157 に答える