私は MongoDB に比較的慣れていませんが、レガシー サービスの前にある種のキャッシュとして使用することを検討しています。この場合、いくつかの問題に遭遇しました。
まず、いくつかの説明。
このキャッシング サービスは、レガシー サービスとクライアントの間にあります。クライアントは、レガシー サービスからデータを取得するキャッシュ サービスに接続します。キャッシング サービスは X 分ごとにデータをフェッチし、MongoDB に保持します。スキーマは非常にシンプルです。多くのキー/値を持つドキュメントです。ネストされたドキュメントなどはありません。さらに、_id を従来のサービスからの一意の ID に設定するため、これも制御できます。
キャッシング サービスがレガシー サービスからデータを取得すると、差分のみが取得されます (最後の取得以降の変更のみ)。したがって、前回から 5 つの「オブジェクト」が変更された場合、それらの 5 つの「オブジェクト」だけが取得されます (ただし、オブジェクトのデルタではなく、完全なオブジェクトが取得されます)。新しい「オブジェクト」がレガシー サービスに追加された場合、それらはもちろんデルタにも含まれます。
私たちの「問題」
私の考えでは、これはアップサートのように聞こえます。新しいオブジェクトがある場合は、それらを挿入します。既存のオブジェクトに変更がある場合は、それらを更新します。ただし、MongoDB は複数のアップサートを特に好まないようです。挿入するだけで重複キーに関するエラーが表示されますが、同じ _id を持つドキュメントが既に存在するため、これは完全に理解できます。upsert パラメーターを取ることができる update 関数は、新しいオブジェクトのリストを取ることはできません。単一のクエリは不可能であるように私には思えます。ただし、ここで何かを完全に見落としている可能性があります。
可能な解決策
さまざまな解決策がいくつかありますが、特に次の 2 つが思い浮かびます。
- 2 つのクエリを実行します。最初に、すべての _id を含むリストを計算します (これらはレガシー サービスから取得したことを思い出してください)。次に、_id リストと一緒に $in 関数を使用してそれらを削除し、すぐに新しいドキュメントを挿入します。これにより、実際にはコレクションが新しいデータで更新されます。実装も簡単です。発生する可能性のある問題は、クライアントが削除と挿入の間にデータを要求し、そのために誤って空の結果を取得することです。これは契約違反であり、絶対に起こり得ません。
- 変更されたオブジェクトごとに 1 つの upsert を実行します。また、実装が非常に簡単で、他のソリューションと同じ問題が発生することはありません。ただし、これには他の(おそらく架空の)問題があります。短時間で何回のアップサートを処理できますか? 毎分 5000 回のアップサートを簡単に処理できるでしょうか? これらは大きなドキュメントではなく、約 20 個のキー/値で、サブドキュメントはありません。この数字はひっそりと引き出されたものであり、実際の数字を予測することは非常に困難です。私の考えでは、このアプローチは間違っているように感じます。新しいドキュメントごとに 1 つのクエリを実行する必要がある理由がわかりません。
提案された2つの解決策とその他の解決策の両方に関して、どんな助けも大歓迎です。余談ですが、テクノロジーは議論の余地がないので、他の種類のデータベースや言語を提案しないでください。私たちが選んだものを選んだ理由は他にもあります:)