tailableカーソル

based on v30 (2010-10-04更新) - オリジナル

tailable カーソルは、 制限付きコレクション (Capped Collections) でのみ使えます。また、取得できるオブジェクトは、 natural order のみです。
インデックスが設定されたフィールドで "tail" をしたい場合には、単純に、 { field : { $gt : value } } で、再度クエリーをするのが簡単です。 tailable カーソルは、それよりは少しだけ速いです。フィールドにインデックスが設定されていない場合で比較すると、tailableカーソルはとても速いです。インデックスなしの状況では、tailableカーソルはとても現実的です。

MongoDBには、Unixの"tail -f"コマンドに似たtailableカーソルという機能があります。

tailable カーソルは、一度すべてのデータを取得した後で閉じません。  このカーソルは最後のオブジェクトの場所を覚えていて、新しいデータが増えた場合、そこから再開することができます。

このカーソルは、コレクションの最後のオブジェクトが返され、かつそれが削除された場合、無効になります。そのため、カーソルが"無効になった”場合に備え、再度クエリをする準備をしておく必要があります。idをチェックすることでそのカーソルが無効かどうかチェックできます。idが0の場合、カーソルは無効ということになります (c++ドライバでは、isDeadを使ってください)。

また、最初のクエリーがどのドキュメントにもマッチしない場合にも、カーソルは無効な状態になります。このケースでも、tailableカーソルを作るためには再クエリーをする必要があります。

MongoDBのプレイケーションでは、マスタサーバでの操作ログ(op log)用のコレクションを追いかけるために、この機能を使っています。 このため、マスタサーバ上の操作ログ(op log)で、書き込みを遅くする可能性のあるindexを作成する必要がないです。

C++ example:

#include "client/dbclient.h"

using namespace mongo;

/* "tail" the namespace, outputting elements as they are added.
   For this to work something field -- _id in this case -- should be increasing
   when items are added.
*/
void tail(DBClientBase& conn, const char *ns) {
  // minKey is smaller than any other possible value
  BSONElement lastId = minKey.firstElement(); 
  // { $natural : 1 } means in forward capped collection insertion order
  Query query = Query().sort("$natural"); 
  while( 1 ) {
    auto_ptr<DBClientCursor> c =
      conn.query(ns, query, 0, 0, 0, QueryOption_CursorTailable);
    while( 1 ) {
      if( !c->more() ) {
		if( c->isDead() ) {
		  // we need to requery
		  break;
		}
		sleepsecs(1); // all data (so far) exhausted, wait for more
		continue; // we will try more() again
      }
      BSONObj o = c->next();
      lastId = o["_id"];
      cout << o.toString() << endl;
    }

    // prepare to requery from where we left off
    query = QUERY( "_id" << GT << lastId ).sort("$natural");
  }
}

参照


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.

These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group.

blog comments powered by Disqus