一意のフィールドをシャードキーとして 使用できない 場合や、複数のフィールドに一意性を適用する必要がある場合は、 プロキシコレクションとして機能する別のコレクションを作成します。
このタスクについて
シャーディングされたクラスターは、ユニークインデックスがシャードキーにある、またはプレフィックスとしてシャードキーが含まれている場合にのみ、シャード全体に一意の制約を強制します。プロキシコレクションはその制約を回避します。プロキシコレクションには元のドキュメントへの参照と一意のキーの両方が含まれており、アプリケーションは最初にプロキシコレクションに書込みます。
プロキシコレクションを使用する場合は、次の点を考慮してください。
アプリケーションは、プロキシコレクションにドキュメントを挿入するときにエラーを検出し、2 つのコレクション間の整合性を強制する必要があります。
プロキシ コレクションでシャーディングが必要な場合は、一意性を強制したい単一フィールドでシャードする必要があります。
各フィールドには独自の プロキシコレクションが必要です。シャーディングされたプロキシ コレクションを使用して複数のフィールドに一意性を強制するには、フィールドごとに 1 つのプロキシコレクションが必要です。 1 つの プロキシコレクションに複数の一意なインデックスを作成した場合、 プロキシコレクションをシャードすることは できません 。
このアプローチでは、ドキュメントの挿入時にMongoDB が自動的に ID を作成するのではなく、
primary_idフィールドに一意のIDを作成する必要があります。
シャーディングされたコレクションの一意のインデックスに適用される制約の完全なセットについては、「 シャーディングされたクラスターで一意性を維持する 」を参照してください。
始める前に
一意の制約 を必要とするが、シャードキーの一部にすることはできないフィールドを識別します。
既存のドキュメントがフィールドの一意の制約に違反していないことを確認します。
手順
ユーザー情報を保存するコレクションrecords について考えてみましょう。フィールドemail はシャードキーではありませんが、一意である必要があります。 proxyコレクションには次のフィールドが含まれています。
{ "_id" : ObjectId("..."), "parent_id" : "<ID>", "email" : "<string>" }
メインコレクションの前に、プロキシコレクションに書き込みます。
ターゲットフィールドと生成された一意のIDを含むドキュメントをproxyコレクションに挿入します。操作が成功した場合は、完全なドキュメントを recordsコレクションに挿入します 。
records = db.getCollection('records'); proxy = db.getCollection('proxy'); var primary_id = ObjectId(); proxy.insertOne({ "_id" : primary_id, "email" : "example@example.net" }) // if: the above operation returns successfully, // then continue: records.insertOne({ "_id" : primary_id, "email": "example@example.net", // additional information... })