翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
機能上の違い: Amazon DocumentDB と MongoDB
Amazon DocumentDB (MongoDB 互換性) と MongoDB の機能上の違いを以下に示します。
Amazon DocumentDB の機能上の利点
暗黙的なトランザクション
Amazon DocumentDB では、複数のドキュメントを変更するオペレーションであってもfindAndModify
、すべてのCRUDステートメント (update
insert
、、、delete
) でアトミック性と一貫性が保証されます。Amazon DocumentDB 4.0 の起動により、マルチステートメントおよびマルチコレクションオペレーションのACIDプロパティを提供する明示的なトランザクションがサポートされるようになりました。Amazon DocumentDB でのトランザクションの使用の詳細については、「Amazon DocumentDB でのトランザクション」を参照してください。
アトミック性および整合性の両方の動作を満たす複数のドキュメントを変更する Amazon DocumentDB のオペレーションの例を次に示します。
db.miles.update( { "credit_card": { $eq: true } }, { $mul: { "flight_miles.$[]": NumberInt(2) } }, { multi: true } )
db.miles.updateMany( { "credit_card": { $eq: true } }, { $mul: { "flight_miles.$[]": NumberInt(2) } } )
db.runCommand({ update: "miles", updates: [ { q: { "credit_card": { $eq: true } }, u: { $mul: { "flight_miles.$[]": NumberInt(2) } }, multi: true } ] })
db.products.deleteMany({ "cost": { $gt: 30.00 } })
db.runCommand({ delete: "products", deletes: [{ q: { "cost": { $gt: 30.00 } }, limit: 0 }] })
updateMany
や deleteMany
などの一括オペレーションを構成する個々のオペレーションはアトミックですが、一括オペレーション全体はアトミックではありません。たとえば、個々の挿入オペレーションがエラーなしで正常に実行された場合、insertMany
オペレーション全体はアトミックです。insertMany
オペレーションでエラーが発生した場合、insertMany
オペレーション内の各挿入ステートメントはアトミックオペレーションとして実行されます。insertMany
、、updateMany
および deleteMany
オペレーションにACIDプロパティが必要な場合は、 トランザクションを使用することをお勧めします。
機能の違いを更新
Amazon DocumentDB は、お客様より依頼のあった機能からさかのぼって、MongoDB との互換性を改善し続けています。このセクションでは、移行とアプリケーション構築を容易にするため、Amazon DocumentDB から削除された機能的な違いについて説明します。
配列インデックス作成
2020 年 4 月 23 日以降、Amazon DocumentDB で 2,048 バイトを超える配列のインデックスを作成する機能がサポートされるようになりました。配列内の個々のキーの制限は依然として 2,048 バイトのままであり、これは MongoDB と一貫しています。
新しいインデックスを作成する場合、強化された機能を利用するためのアクションは必要ありません。既存のインデックスがある場合、インデックスを削除してから再作成することで、強化された機能を利用できます。強化された機能を使用した現在のインデックスバージョンは "v" : 3
です。
注記
本番クラスターの場合、インデックスの削除はアプリケーションのパフォーマンスに影響を与える可能性があります。本番システムに変更を加える場合、最初にテストし、注意して進めることをお勧めします。さらに、インデックスの再作成にかかる時間は、コレクションの全体的なデータサイズの関数になります。
次のコマンドを使用して、インデックスのバージョンをクエリできます。
db.collection.getIndexes()
このオペレーションによる出力は、次のようになります。この出力では、インデックスのバージョンは "v" : 3
です。これは最新のインデックスバージョンです。
[
{
"v" : 3,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.test"
}
]
マルチキーインデックス
2020 年 4 月 23 日より、Amazon DocumentDB では同じ配列内に複数のキーを持つ複合インデックスを作成する機能がサポートされるようになりました。
新しいインデックスを作成する場合、強化された機能を利用するためのアクションは必要ありません。既存のインデックスがある場合、インデックスを削除してから再作成することで、強化された機能を利用できます。強化された機能を使用した現在のインデックスバージョンは "v" : 3
です。
注記
本番クラスターの場合、インデックスの削除はアプリケーションのパフォーマンスに影響を与える可能性があります。本番システムに変更を加える場合、最初にテストし、注意して進めることをお勧めします。さらに、インデックスの再作成にかかる時間は、コレクションの全体的なデータサイズの関数になります。
次のコマンドを使用して、インデックスのバージョンをクエリできます。
db.collection.getIndexes()
このオペレーションによる出力は、次のようになります。この出力では、インデックスのバージョンは "v" : 3
です。これは最新のインデックスバージョンです。
[
{
"v" : 3,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.test"
}
]
文字列の Null 文字
2020 年 6 月 22 日現在、Amazon DocumentDB が文字列で null 文字 ('\0'
) をサポートするようになりました。
ロールベースアクセスコントロール
2020 年 3 月 26 日現在、Amazon DocumentDB は組み込みロールのロールベースのアクセスコントロール (RBAC) をサポートしています。詳細については、「ロールベースのアクセスコントロール」を参照してください。
$regex
インデックス作成
2020 年 6 月 22 日現在、Amazon DocumentDB は $regex
演算子がインデックスを活用する機能をサポートするようになりました。
$regex
演算子を使用してインデックスを活用するには、hint()
コマンドを使用する必要があります。hint()
を使用する際は、$regex
を適用するフィールドの名前を指定する必要があります。たとえば、product
というフィールドにインデックス名 p_1
というインデックスがある場合、db.foo.find({product: /^x.*/}).hint({product:1})
では p_1
インデックスを使用しますが、db.foo.find({product: /^x.*/}).hint(“p_1”)
ではインデックスを使用しません。インデックスが選択されているかどうかを確認するには、explain()
コマンドを使用するか、低速クエリのログ記録にプロファイラーを使用します。例えば、db.foo.find({product: /^x.*/}).hint(“p_1”).explain()
と指定します。
注記
hint()
メソッドは、一度に 1 つのインデックスでのみ使用できます。
$regex
クエリでのインデックスの使用は、プレフィックスを利用し、I
、m
、または o
正規表現オプションを指定しない正規表現クエリに最適化されます。
$regex
でインデックスを使用する場合は、重複値の数がコレクション内のドキュメントの総数の 1% 未満であるごく一部のフィールドにインデックスを作成することをお勧めします。例えば、コレクションに 100,000 個のドキュメントが含まれている場合、同じ値が発生する回数が 1000 回以下のフィールドにのみインデックスを作成します。
ネストされたドキュメントの投影
Amazon DocumentDB と MongoDB 3.6 における $project
演算子と機能の差は、Amazon DocumentDB 4.0 で解決されていますが、Amazon DocumentDB 3.6 では未サポートのままです。
Amazon DocumentDB 3.6 は、投影を適用するときにネストされたドキュメントの最初のフィールドのみを考慮しますが、MongoDB 3.6 はサブドキュメントを解析し、各サブドキュメントにも投影を適用します。
例えば、投影が “a.b.c”: 1
とすると、この動作は Amazon DocumentDB と MongoDB の両方で期待どおりに機能します。ただし、投影が {a:{b:{c:1}}}
だとすると、Amazon DocumentDB 3.6 は投影を a
にのみ適用し、b
や c
には適用しません。Amazon DocumentDB 4.0では、投影 {a:{b:{c:1}}}
は a
、b
、およびc
に適用されます。
MongoDB との機能的な違い
トピック
$vectorSearch
operator
Amazon DocumentDB は、独立した演算子$vectorSearch
として をサポートしていません。代わりに、 $search
演算子vectorSearch
内で がサポートされています。詳細については、「Amazon DocumentDB のベクトル検索」を参照してください。
OpCountersCommand
Amazon DocumentDB の OpCountersCommand
動作は MongoDB の opcounters.command
動作と次のように異なります。
MongoDB は挿入、更新、
opcounters.command
削除を除くすべてのコマンドをカウントしますが、Amazon DocumentDB はOpCountersCommand
コマンドも除外します。find
Amazon DocumentDB は、いくつかの内部コマンドを にカウントします
OpCountersCommand
。
管理者データベースとコレクション
Amazon DocumentDB は管理者データベースまたはローカルデータベースをサポートしていません。また、MongoDB system.*
または startup_log
コレクションもサポートしていません。
cursormaxTimeMS
Amazon DocumentDB では、cursor.maxTimeMS
はカウンターを getMore
リクエストごとにリセットします。したがって、3000 ミリ秒 maxTimeMS
が指定されている場合、クエリは 2800 ミリ秒 になり、getMore
リクエストは 300 ミリ秒 かかり、カーソルはタイムアウトしません。カーソルがタイムアウトするのは、単一のオペレーション(クエリまたは個々の getMore
リクエスト)の場合のみです。指定された maxTimeMS
よりも多くかかります。さらに、カーソルの実行時間をチェックするスイーパーは、5 分単位で実行されます。
explain()
Amazon DocumentDB は、分散型で耐障害性に優れた自己修復ストレージシステムを利用する専用のデータベースエンジンAPIで MongoDB 4.0 をエミュレートします。その結果、クエリプランと explain()
の出力は、Amazon DocumentDB と MongoDB の間で異なる場合があります。クエリプランを制御する場合は、$hint
演算子を使用して優先インデックスの選択を強制できます。
フィールド名の制限
Amazon DocumentDB はドット「.」をサポートしていません。ドキュメントフィールド名では、(例 : db.foo.insert({‘x.1’:1})
)。
Amazon DocumentDB では、フィールド名の $ プレフィックスもサポートしていません。
例えば、Amazon DocumentDB または MongoDB で次のコマンドを試してください。
rs0:PRIMARY< db.foo.insert({"a":{"$a":1}})
MongoDB は以下を返します。
WriteResult({ "nInserted" : 1 })
Amazon DocumentDB はエラーを返します。
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 2, "errmsg" : "Document can't have $ prefix field names: $a" } })
注記
この機能の違いには例外があります。$ プレフィックスで始まる次のフィールド名はホワイトリストに登録されており、Amazon DocumentDB で正常に使用できます : $id、$ref、$db。
インデックスビルド
Amazon DocumentDB では、任意の時点でコレクションにおいてインデックスの作成が 1 つのみ許可されます。フォアグラウンドまたはバックグラウンドのいずれかで実行されます。インデックス構築が現在進行中のときに、createIndex()
または dropIndex()
などの操作が同じコレクションで発生した場合、新しく試行された操作は失敗します。
デフォルトでは、Amazon DocumentDB と MongoDB バージョン 4.0 のインデックスビルドはバックグラウンドで行われます。MongoDB バージョン 4.2 以降では、 createIndexes またはそのシェルヘルパー createIndex()
および に指定されている場合、バックグラウンドインデックスビルドオプションは無視されますcreateIndexes()
。
Time to Live (TTL) インデックスは、インデックス構築の完了後に期限切れのドキュメントを開始します。
パスに空のキーでルックアップ
パスの一部として (例 : x.
、x..b
) 空の文字列を含むキーを調べると、オブジェクトには空の文字列キーパス (例 : {"x" : [ { "" : 10 }, { "b" : 20 } ]}
) が配列内にあり、Amazon DocumentDB は MongoDB で同じルックアップを実行する場合とは異なる結果を返します。
MongoDB では、空の文字列キーがパスルックアップの末尾にない場合に、配列内の空のキーパスルックアップが期待どおりに機能します。ただし、空の文字列キーがパスルックアップの末尾にある場合、配列は検索されません。
ただし、Amazon DocumentDB では、配列内の最初の要素のみが読み取られます。getArrayIndexFromKeyString
は空の文字列を0
に変換するため、文字列キールックアップは配列インデックスルックアップとして扱われるためです。
MongoDB APIs、オペレーション、およびデータ型
Amazon DocumentDB は MongoDB 3.6 および 4.0 と互換性がありますAPIs。サポートされている機能のリストについては、 up-to-date 「」を参照してくださいAmazon DocumentDB でサポートされている MongoDB APIs、オペレーション、およびデータ型。
mongodump
および mongorestore
ユーティリティ
Amazon DocumentDB は管理者データベースをサポートしないため、mongodump
または mongorestore
ユーティリティを使用するときに、管理者データベースをダンプまたは復元しません。mongorestore
を使用して、Amazon DocumentDB の新しいデータベースを作成するときに、復元オペレーションに加えてユーザーロールを再作成する必要があります。
注記
Amazon DocumentDB には、バージョン 100.6.1 までの MongoDB データベースツールをお勧めします。MongoDB データベースツールのダウンロードには、こちら
結果の順序付け
Amazon DocumentDB では、結果セットの暗黙的な並べ替え順序は保証されません。結果セットの順序を確実にするには、sort()
を使用してソート順を明示的に指定します。
次の例では、在庫フィールドに基づいて、インベントリ収集の項目を降順にソートします。
db.inventory.find().sort({ stock: -1 })
$sort
集約ステージを使用する場合は、$sort
ステージが、集約パイプラインの最後のステージでない限り、並べ替え順序は保持されません。$sort
集約ステージと組み合わせた $group
集約ステージを使用する場合、$sort
集約ステージはおよび $first
および $last
アキュムレータにのみ適用されます。Amazon DocumentDB 4.0 では、$push
のサポートが追加され、前の $sort
ステージ並べ替え順序を尊重します。
再試行可能な書き込み
MongoDB 4.2 互換ドライバーから、再試行可能な書き込みがデフォルトで有効になっています。ただし、Amazon DocumentDB は現在、再試行可能な書き込みをサポートしていません。機能の違いは、次のようなエラーメッセージで示されます。
{"ok":0,"errmsg":"Unrecognized field: 'txnNumber'","code":9,"name":"MongoError"}
再試行可能な書き込みは、接続文字列 (例: MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false"))
または MongoClient コンストラクターのキーワード引数 (例: MongoClient("mongodb://my.mongodb.cluster/db", retryWrites=False))
。
次に、接続文字列の再試行可能な書き込みを無効にする Python の例を示します。
client = pymongo.MongoClient('mongodb://
<username>
:<password>
@docdb-2019-03-17-16-49-12.cluster-ccuszbx3pn5e.us-east-1.docdb.amazonaws.com:27017/?replicaSet=rs0',w='majority',j=True,retryWrites=False)
スパースインデックス
クエリで作成したスパースなインデックスを使用するには、インデックスをカバーするフィールドで $exists
句を使用する必要があります。$exists
を省略した場合、Amazon DocumentDB はスパースなインデックスを使用しません。
次に例を示します。
db.inventory.count({ "stock": { $exists: true }})
スパースなマルチキーインデックスの場合、ドキュメントのルックアップによって値のセットが生成され、インデックス付きフィールドのサブセットのみが見つからない場合、Amazon DocumentDB は一意キー制約をサポートしません。たとえば、"a" : [ { "b" : 2 }, { "c" : 1 } ]
を入力すると、"a.c"
がインデックスに格納されているため、createIndex({"a.b" : 1 }, { unique : true, sparse :true })
はサポートされません。
$all
式$elemMatch
内での の使用
Amazon DocumentDB は $elemMatch
演算子が $all
内にある表現の使用をサポートしていません。回避策として、次のように $and
演算子を $elemMatch
で使用できます。
元のオペレーション:
db.col.find({ qty: { $all: [ { "$elemMatch": { part: "xyz", qty: { $lt: 11 } } }, { "$elemMatch": { num: 40, size: "XL" } } ] } })
更新されたオペレーション:
db.col.find({ $and: [ { qty: { "$elemMatch": { part: "xyz", qty: { $lt: 11 } } } }, { qty: { "$elemMatch": { qty: 40, size: "XL" } } } ] })
$ne
、$nin
、$nor
、$not
、$exists
、および $elemMatch
インデックス作成
Amazon DocumentDB は、現在、$ne
、$nin
、$nor
、$not
、$exists
、と $distinct
の演算子でのインデックス使用をサポートしていません。そのため、これらの演算子を利用した結果は、収集スキャンになります。これらの演算子のいずれかを使用する前にフィルターまたは照合を実行すると、スキャン対象のデータ量が減り、パフォーマンスが向上します。
Amazon DocumentDB では、Amazon DocumentDB 5.0 とエラスティッククラスターの $elemMatch
オペレーターによるインデックススキャンのサポートが追加されました。インデックススキャンは、クエリのみのフィルタに 1 つのレベルの $elemMatch
フィルタがある場合はサポートされますが、ネストされた $elemMatch
クエリが含まれる場合はサポートされません。
Amazon DocumentDB 5.0 でのインデックススキャンをサポートする $elemMatch
クエリシェイプ:
db.foo.find( { "a": {$elemMatch: { "b": "xyz", "c": "abc"} } })
Amazon DocumentDB 5.0 でインデックススキャンをサポートしない $elemMatch
クエリシェイプ:
db.foo.find( { "a": {$elemMatch: { "b": {$elemMatch: { "d": "xyz", "e": "abc"} }} } })
$lookup
Amazon DocumentDB は、等価一致 (左外部結合など) を行う機能をサポートし、相関関係のないサブクエリもサポートしますが、相関関係のあるサブクエリはサポートしません。
$lookup
でインデックスを利用する
$lookup
ステージ演算子で、インデックスを利用できるようになりました 。ユースケースに基づいて、パフォーマンスを最適化するために使用できるインデックス作成アルゴリズムが複数あります。このセクションでは、$lookup
のさまざまなインデックス作成アルゴリズムについて説明し、ワークロードに最適なオプションを選択するのに役立ちます。
デフォルトでは、Amazon DocumentDB は allowDiskUse:false
が使用された場合はハッシュアルゴリズムを使用し、allowDiskUse:true
が使用された場合はソートマージを使用します。ユースケースによっては、クエリオプティマイザで別のアルゴリズムを使用するように強制することが望ましい場合があります。以下は、集約演算子が利用できる、さまざまな $lookup
インデックス作成アルゴリズムです。
ネストループ: 外部コレクションが 1 GB 未満で、外部コレクションのフィールドにインデックスがある場合は、通常、ネストループプランがワークロードに役立ちます。ネスト・ループ・アルゴリズムを使用している場合、説明プランではステージが
NESTED_LOOP_LOOKUP
と表示されます。ソートマージ: ソートマージプランは、外部コレクションのルックアップに使用されるフィールドにインデックスがなく、作業データセットがメモリに収まらない場合にワークロードにとって有益です。ソートマージアルゴリズムが使用されている場合、説明プランではステージを
SORT_LOOKUP
と表示されます。ハッシュ: 外部コレクションが 1 GB 未満で、作業データセットがメモリに収まる場合は、通常、ハッシュプランがワークロードにとって有益です。ハッシュアルゴリズムが使用されている場合、説明プランはステージを
HASH_LOOKUP
と表示されます。
クエリに対して explain を使用することで、$lookup
演算子に使用されているインデックス作成アルゴリズムを特定できます。以下に例を示します。
db.localCollection.explain(). aggregate( [ { $lookup: { from: "foreignCollection", localField: "a", foreignField: "b", as: "joined" } } ] output { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.localCollection", "winningPlan" : { "stage" : "SUBSCAN", "inputStage" : { "stage" : "SORT_AGGREGATE", "inputStage" : { "stage" : "SORT", "inputStage" : { "stage" : "NESTED_LOOP_LOOKUP", "inputStages" : [ { "stage" : "COLLSCAN" }, { "stage" : "FETCH", "inputStage" : { "stage" : "COLLSCAN" } } ] } } } } }, "serverInfo" : { "host" : "devbox-test", "port" : 27317, "version" : "3.6.0" }, "ok" : 1 }
explain()
メソッドを使用する代わりに、プロファイラを使用して、$lookup
演算子の使用で利用されているアルゴリズムを表示することができます。プロファイラーの詳細については、「Amazon DocumentDB オペレーションのプロファイリング」を参照してください。
planHint
を使用する
クエリオプティマイザで別のインデックス作成アルゴリズムと $lookup
を強制的に使用する場合、planHint
を使用できます。これを行うには、集約ステージオプションのコメントを使用して、別のプランを強制します。コメントの構文の例を以下に示します。
comment : { comment : “<string>”, lookupStage : { planHint : “SORT” | “HASH” | "NESTED_LOOP" } }
以下は、planHint
を使用してクエリオプティマイザに HASH
インデックスアルゴリズムの使用を強制する例です。
db.foo.aggregate( [ { $lookup: { from: "foo", localField: "_id", foreignField: "_id", as: "joined" }, } ], { comment : "{ \\"lookupStage\\" : { \\"planHint\\": \\"HASH\\" }}"
どのアルゴリズムがワークロードに最適かをテストするには、executionStats
パラメータにある explain
メソッドを使用して、$lookup
ステージの実行時間を測定することができ、これはインデックス作成アルゴリズム (つまり、HASH
/ SORT
/NESTED_LOOP
) を変更しながらできます。
次の例は executionStats
を使用して、$lookup
ステージの実行時間を測定するには、SORT
アルゴリズムを使用します。
db.foo.explain(“executionStats”).aggregate( [ { $lookup: { from: "foo", localField: "_id", foreignField: "_id", as: "joined" }, } ], { comment : "{ \\"lookupStage\\" : { \\"planHint\": \\"SORT\\" }}"