あなた
少し前に、1つの小さなプロジェクトの管理パネルを作成し、その中のいくつかの重要なイベントのログを表示するといいと思いました。 記憶力は、私が聞いたことがあるが実際には実行したことのないMongoDbの機能の1つである、調整可能なカーソルを思い出させてくれました。
どんな獣?
デフォルトでは、クライアントがカーソルで使用可能なすべてのデータを受信した後、mongoは自動的に接続を閉じます。 制限された(キャップされた)コレクションの場合、追加の動作、いわゆるテールカーソルが可能です。
テールカーソルは開いたままで、検索基準を満たす新しいデータを受信し続けます。 彼らの行動はおなじみのtail -fを連想させます。 Mongoはテールカーソルを使用してopplogを追跡します。
あなたが必要なもの、私は思った
new Thread(new Runnable() { @Override public void run() { DBCollection collection=MongoConnector.getInstance().getCollection("events"); // addOption DBCursor cur= collection.find().addOption(Bytes.QUERYOPTION_TAILABLE).addOption(Bytes.QUERYOPTION_AWAITDATA); while (cur.hasNext()) { // , , JS wsConnection.broadcast((String) cur.next().get("message")); } } }).start();
ところで、実践が示しているように、新しいドキュメントを挿入してからテールカーソルでクライアントが受信するまでの遅延は非常に小さいため、原則として無視することができます。
軟膏で飛ぶ
公式文書では、多くの書き込み操作を伴うコレクションでテールカーソルを使用すると、非常にコストがかかることが示されています。 インデックスが存在するフィールドでクエリが構築されている場合、多数のレコードがある場合は、定期的に新しいドキュメントを要求して、通常のカーソルを使用することをお勧めします
どのように機能しますか?
上記を覚えておいて、私はテールカーソルの仕事をtail -fの仕事のように書きましたか? 実際、一見すると思われるよりもさらに多くの類似点があります。
最後のドキュメントに到達してテールカーソルを設定し、そこからデータを読み取ると、mongoはカーソルをその上に残し、コレクション記述子を監視します。要求を満たす新しい要素が表示されると、カーソルはそこに移動します。
通常の(無制限の)コレクションの場合、この動作は不可能です。ドキュメントがディスクに保存される順序は、データ挿入の順序と必ずしも一致しないためです。
世界に衝撃を与えたテールカーソルに関する4つの事実
1)テールカーソルはインデックスを使用せず、ディスクに格納されている順序でドキュメントを返します。 限られたコレクションの場合、配置順序は常にドキュメントの挿入順序と一致します。
2)インデックスは使用されないため、クエリの最初にコレクション内のすべてのレコードを読み取る必要があります。これは、大量のデータがあるため、非常に高価になる可能性があります。 すでに利用可能なデータを受け取った後、要求を満たさない新しく追加されたドキュメントのスクリーニングは不採算ではありません。
3)次の場合、テールカーソルが無効になる可能性があります(コレクションの追跡はありません)。
最初の検索クエリに一致するドキュメントはありませんでした。
最後のドキュメントは、カーソルが指し示した瞬間に削除されました。
4)デッドカーソルのIDは0です