web-dev-qa-db-ja.com

Pymongo / MongoDB:インデックスを作成するか、インデックスを確保しますか?

Pymongoの_create_index_と_ensure_index_の違いがわかりません。 MongoDBインデックスページ では、

ensureIndex()を呼び出してインデックスを作成できます

ただし、pymongoには、2つの異なるコマンド _create_index__ensure_index_ があり、インデックスの作成に関するドキュメントには以下があります。

インデックスを無条件に作成しようとするcreate_index()とは異なり、ensure_index()はドライバ内のキャッシュを利用して、存在しない可能性のあるインデックスのみを作成しようとします。 PyMongoによってインデックスが作成(または確認)されると、ttl秒間「記憶」されます。その制限時間内にensure_index()を繰り返し呼び出すと軽量になります-実際にインデックスを作成しようとしません。

_ensure_index_が永続的なインデックスを作成することを理解するのは正しいのでしょうか、それとも_create_index_を使用する必要がありますか?

48
YXD

Mongo 3.xでは、 ensureIndex は推奨されておらず、推奨されないことに注意してください。

バージョン3.0.0から非推奨:db.collection.ensureIndex()はdb.collection.createIndex()のエイリアスになりました。

pymongo でも同じです:

非推奨-このコレクションにインデックスが存在することを確認します。

つまり、常にcreate_indexを使用する必要があります。

14
Salvador Dali

@ andreas-jungはensure_index()create_index()のラッパーであるという点で正しいです。私はこの句で混乱が生じると思います。

PyMongoによってインデックスが作成(または確認)されると、ttl秒間「記憶」されます。

インデックスが一時的または「一時的」であることではありません。指定された秒数の間に、同じインデックスを再度作成しようとするensure_index()の呼び出しが notは何らかの効果があり、notcreate_index()を呼び出しますが、その後は「キャッシュ」有効期限が切れると、ensure_index()willの呼び出しが再びcreate_index()を呼び出します。

率直に言って、PyMongoのドキュメントはこれがどのように機能するかを説明するのにあまり役に立たないので、私はあなたの混乱を完全に理解していますが、 Ruby docs に目を向けると、説明が少し明確になります:

  • (文字列)ensure_index(spec、opts = {})

Create_indexを呼び出し、フラグを設定して、さらにX分間、フラグを再度設定しないようにします。 Mongo :: DBオブジェクトをoptions [:cache_time]として初期化するときに、この時間をオプションとして指定できます。インデックスへの変更は、キャッシュ時間に関係なく伝播されます(たとえば、インデックスの方向の変更)

このメソッドのパラメーターとオプションは、Collection#create_indexのものと同じです。

例:

_Call sequence:_

Time t: @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and sets the 5 minute cache

Time t+2min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- doesn't do anything

Time t+3min : @posts.ensure_index([['something_else', Mongo::ASCENDING]) -- calls create_index and sets 5 minute cache

Time t+10min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and resets the 5 minute counter

私は、ドライバーがまったく同じように機能すると主張しているわけではありません。単に説明のために、彼らの説明が私見より少し良いというだけです。

39
Juan Gomez

インタラクティブシェルのensureIndexメソッドとpythonドライバーのensure_indexは異なるものですが、同じWordが使用されます。 pythonドライバーのcreate_indexメソッドとensure_indexメソッドは両方とも、インデックスを永続的に作成します。

おそらく、ensure_indexが呼び出すたびにインデックスを再作成するかどうかわからないので、そのような状況では合理的なTTLでcreate_indexを使用するでしょう。通常、レクリエーションは望ましくなく、重い操作になる可能性があります。しかし、(pythonまたはRubyドライバーの)ensure_indexでも、TTLの有効期限が切れたとき、または別のクライアントインスタンスから呼び出したとき、または再起動後にインデックスを再作成できます。これについてはわかりません。

おそらく、インデックスが既に存在する場合は、メソッドindex_information()を使用して最初にチェックすることをお勧めします。既に存在する場合、再度作成することはありません。

私は今、用語ensure_index(またはensureIndex)が2つの異なる意味でどのように使用されるかを示しています。

1)データベースにまだ存在しない場合はインデックスを作成します

これはInteractive ShellメソッドensureIndex()が行うことです:

http://www.mongodb.org/display/DOCS/Indexes#Indexes-Basics

また、Node.JS MongoDB Driverは次のように動作します。

https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js

(ファイルfunction ensureIndexcollection.jsを検索します。)

2)「ドライバーキャッシュ」にない場合はインデックスを作成します

ここでは同じ識別子が異なる意味で使用されていますが、これはわかりにくいと思います。

pythonおよびRubyドライバーは、最近作成されたインデックスに関する情報をメモリに保存し、この動作を「キャッシュ」と呼びます。

このキャッシュについてデータベースに通知しません。

このメカニズムの結果は、TTL値(有効期間)でcreate_indexまたはensure_indexを初めて呼び出すと、ドライバーはデータベースにインデックスを挿入し、この挿入を記憶し、メモリ内のTTL情報。ここでキャッシュされるのは、時間とインデックスでした。

同じドライバインスタンスで同じコレクションの同じインデックスを使用して次回ensure_indexを呼び出すと、ensure_indexコマンドは最初の呼び出しからTTL秒がまだ経過していない場合にのみインデックスを再度挿入します。

create_indexを呼び出すと、最初の呼び出しからどれだけ時間が経過しても、そしてもちろんこれが最初の呼び出しである場合でも、常にインデックスが挿入されます。

これはpythonドライバーです。ファイルdef ensure_indexcollection.pyを検索します。

https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py

Rubyドライバーは、ファイルdef ensure_indexcollection.rbを検索します。

https://github.com/mongodb/mongo-Ruby-driver/blob/master/lib/mongo/collection.rb

(異なるクライアントインスタンスは他のインスタンスのキャッシングについて知らないことに注意してください。この情報はメモリのみに保持され、インスタンスごとです。クライアントアプリケーションを再起動すると、新しいインスタンスは古い「キャッシュ」インデックス挿入を認識しません。また、他のクライアントは知りません、彼らはお互いに言いません。)

pythonドライバーまたはRubyドライバーが既にそこにあるインデックスを挿入すると、dbで何が起こるかを完全に理解できませんでした。この場合、彼らは何もしないと思いますが、これはより理にかなっており、Interactive ShellとJSドライバーの動作にも一致します。

9
mit

Allインデックスは永続的です。 ensure_index()はcreate_index()の小さなラッパーです。

"" "ensureIndex()関数は、存在しない場合にのみインデックスを作成します。" ""

一時インデックスまたは一時インデックスのようなものはありません。

3
Andreas Jung