這時可以利用以下的 script 來達成!
這裡假設 Collection 的名稱是 Coll,裡面的每筆資料(每個文件)都有 time 跟 message 兩個欄位。
tail.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Get the started position. var start_index = db.Coll.find().count()-10; while ( true ) { // if (db.Coll.find().count() >= start_index) { var index = start_index - 1; // Get the next document with ignoring previous old messages. var rec = db.Coll.find().skip(index); print(rec[0].time + " | " + rec[0].message); start_index++; } // Sleep for 100 ms. sleep(0.1); } function sleep( milliseconds ) { var timer = new Date(); var time = timer.getTime(); do timer = new Date(); while ( (timer.getTime() - time) < milliseconds ); } |
sleep 部分的 JavaScript 取自 [3]。
tail.sh
1 |
{MONGO_PATH} /bin/mongo --quiet localhost:27017/{DB_NAME} . /tail .js |
(假設 MongoDB 沒有更改連接埠,因此連線對象是 localhost: 27017)
這個寫法雖然可以動,不過已知會有幾個問題:
1、目前寫法是 sleep 0.1 秒後只會拿出一筆資料,而沒有辦法一次一整沱一起印出來
2、因為 MongoDB 的 script 好像不支援 window,所以沒有 setTimeout() 可以使用,只能用應該很浪費系統資源的迴圈來達到 sleep 的效果。
第一點可能有一些方法可以解決,例如把 while 迴圈改成以下的寫法:
1 2 3 4 5 6 7 8 9 10 11 |
while ( true ) { if (db.Coll.find().count() >= start_index) { var index = start_index - 1; // Get the next document with ignoring previous old messages. db.Coll.find().skip(index).forEach( function (rec) { print(rec.time + " | " + rec.message); start_index++; }); } sleep(100); } |
如果想要減少 I/O 次數,也許還可以考慮 print 改成暫存在某個變數裡,等到迴圈結束要 sleep 之前才一次印出。
第二點目前還不知道有沒有其他更好的 sleep 寫法,所以暫時不解決。
參考資料:
1、mongodb: how to get the last N records?
2、MongoDB: Create Tailable Cursor
3、[小筆記] Javascript 中實現 sleep 的方法
沒有留言:
張貼留言