サーチ…


備考

Mongoのコレクションについて考えてみるには、Who、What、When、Where、Why、Howという観点から考えるのが便利です。 Mongoはさまざまな種類のデータに対して以下の最適化を行っています:

どこ - GeoJSON
When - ObjectIDタイムスタンプ
Who - 流星口座文字列
方法 - デシジョンツリー用のJSON

Mongoのデフォルト文書は「What」を大まかに表しています。

レガシーデータベースへのレコードの作成

idGenerationフィールドを使ってコレクションを定義することで、通常のMongoフォーマットをデフォルトにすることができます。

MyCollection = new Meteor.Collection('mycollection', {idGeneration : 'MONGO'});

ドキュメントへのデータの挿入

Mongo初心者の多くは、配列、日付、ブール値、セッション変数などをドキュメントレコードに挿入する方法など、基本について悩まされています。この例では、基本的なデータ入力に関するガイダンスを提供しています。

Todos.insert({
  text: "foo",                        // String
  listId: Session.get('list_id'),     // String
  value: parseInt(2),                 // Number
  done: false,                        // Boolean
  createdAt: new Date(),              // Dimestamp
  timestamp: (new Date()).getTime(),  // Time
  tags: []                            // Array
});

最近作成したドキュメントの_idを取得する

同期的に取得することもできます:

var docId = Todos.insert({text: 'foo'});
console.log(docId);

または非同期に:

Todos.insert({text: 'foo'}, function(error, docId){
  console.log(docId);
});

タイムズデータ

MongoDBを時系列データに使用することは、公式のホワイトペーパーとプレゼンテーションとともに、非常にうまく文書であり、ユースケースを確立しています。時系列データ用の独自のスキーマを作成する前に、MongoDBの公式ドキュメントを読み、見てください。

時系列データ用MongoDB

一般的には、あなたのtimeseriesデータ用のバケツを作成したいと思うでしょう:

DailyStats.insert({
   "date" : moment().format("MM-DD-YYYY"),
   "dateIncrement" : moment().format("YYYYMMDD"),
   "dailyTotal" : 0,
   'bucketA': 0,
   'bucketB': 0,
   'bucketC': 0
   });

そして、あなたのアプリケーションにデータが供給されるときにそれらのバケットをインクリメントします。この増分は、Meteor Method、コレクションオブザーバ、REST APIエンドポイント、およびその他のさまざまな場所に置くことができます。

DailyStats.update({_id: doc._id}, {$inc: {bucketA: 1} });

より完全な流星の例については、「臨床流星」トラックの例を参照してください。

リアルタイムアナリティクスパイプライン
臨床流星 - グラフ - Dailystats

正規表現によるフィルタリング

正規表現、リアクティブセッション変数、およびdeps自動実行を使用して、サーバー上のサブスクリプションをフィルタリングするための単純なパターン。

// create our collection
WordList =  new Meteor.Collection("wordlist");

// and a default session variable to hold the value we're searching for
Session.setDefault('dictionary_search', '');

Meteor.isClient(function(){
    // we create a reactive context that will rerun items when a Session variable gets updated 
    Deps.autorun(function(){
        // and create a subscription that will get re-subscribe to when Session variable gets updated
        Meteor.subscribe('wordlist', Session.get('dictionary_search'));
    });

    Template.dictionaryIndexTemplate.events({
        'keyup #dictionarySearchInput': function(evt,tmpl){
            // we set the Session variable with the value of our input when it changes
            Session.set('dictionary_search', $('#dictionarySearchInput').val());
        },
        'click #dictionarySearchInput':function(){
            // and clear the session variable when we enter the input
            Session.set('dictionary_search', '');
        },
    });
});
Meteor.isServer(function(){
    Meteor.publish('wordlist', function (word_search) {
        // this query gets rerun whenever the client subscribes to this publication
        return WordList.find({
            // and here we do our regex search
            Word: { $regex: word_search, $options: 'i' }
        },{limit: 100});
    });
});

そして、クライアントで使用されるHTML:

<input id="dictionarySearchInput" type="text" placeholder="Filter..." value="hello"></input>

このパターン自体はかなり単純ですが、正規表現はそうではないかもしれません。正規表現に慣れていない場合は、以下の便利なチュートリアルやリンクを参考にしてください:

正規表現チュートリアル
正規表現チートシート
Javascriptでの正規表現

地理空間コレクション - もっと学ぶ

地理空間コレクションには一般にGeoJSONをMongoデータベースに格納し、そのデータをクライアントにストリーミングし、ブラウザのwindow.navigator.geolocationアクセスし、Map APIをロードし、GeoJSONをLatLngsに変換し、マップ上にプロットする。好ましくは、すべてリアルタイムで。開始するためのリソースのリストは次のとおりです。

コレクションクエリの監査

次の例では、すべての収集クエリをリアルタイムでサーバーコンソールに記録します。

Meteor.startup(     
  function () {     
    var wrappedFind = Meteor.Collection.prototype.find;     

    // console.log('[startup] wrapping Collection.find')        

    Meteor.Collection.prototype.find = function () {        
      // console.log(this._name + '.find', JSON.stringify(arguments))       
      return wrappedFind.apply(this, arguments);        
    }       
  },        

  function () {     
    var wrappedUpdate = Meteor.Collection.prototype.update;     

    // console.log('[startup] wrapping Collection.find')        

    Meteor.Collection.prototype.update = function () {      
      console.log(this._name + '.update', JSON.stringify(arguments))        
      return wrappedUpdate.apply(this, arguments);      
    }       
  }     
);      

オブザーバー&ワーカー機能

ノードイベントループが自転車チェーンのように動作する場合、サーバー側のコレクションオブザーバはディレイラーのようなものです。これは、データが入ってくるときにデータ収集に乗るギアリングの仕組みです。すべてのレースバイクにはディレイラーがあるため、非常に効果的です。しかし、それはまたシステム全体を破壊するための源でもあります。それはあなたに爆破する高速反応機能です。警告してください。

Meteor.startup(function(){
  console.log('starting worker....');

  var dataCursor = Posts.find({viewsCount: {$exists: true}},{limit:20});

  var handle = dataCursor.observeChanges({
    added: function (id, record) {
      if(record.viewsCount > 10){
         // run some statistics
         calculateStatistics();

         // or update a value
         Posts.update({_id: id}, {$set:{
           popular: true
         }});

      }
    },
    removed: function () {
      console.log("Lost one.");
    }
  });
});

ディレイラーの大きさは20本に制限されています....歯の数はいくつですか?より具体的には、コレクション上を歩いているときにカーソル内にあるアイテムの数この種の関数では、 'var'キーワードの使用には注意が必要です。可能な限り少ない数のオブジェクトをメモリに書き込み、追加されたメソッド内のオブジェクトの再利用に焦点を合わせます。 opslogがオンになっていて、このことが最高速度になると、Nodeガーベッジコレクターがオブジェクトをメモリヒープに書き込んでいるときに、オブジェクトをきれいにすることができます。

各メテオインスタンスが同じレコードを更新しようとしているので、上記の解決法は水平方向にはうまくスケールされません。ですから、これを水平方向に拡大するには何らかの環境検出が必要です。

クラスタ内の複数のマシン間でサービスワーカーを同期させる優れた例については、 percolatestudios:synced-cronパッケージを参照してください。
流星シンクロ



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow