2017-10-03 5 views

答えて

2

シンプルなソリューション

あなたが書かれているゲームの結果の数が多くて1秒に1回になります知っているなら、あなたは別の文書average/scoreを更新するために、クラウド機能を使用することができます。各ゲーム結果の追加について、文書が存在しない場合は、countというフィールドを1に、scoreというフィールドをゲームのスコアに設定します。文書が存在する場合は、countというフィールドに1を追加し、scoreというフィールドにスコアを追加します。

平均スコアを照会するには、average/scoreと入力し、scorecountで割ってください。

スケーラブルなソリューション

あなたが疑われるか、書き込まれているゲームの結果の数が毎秒1回超えたことを知っている場合は、簡単な解決策の分散カウンタースタイルを適用する必要があります。

平均文書のためのデータ・モデルは、サブコレクションを使用すると、次のようになります。

更新
// ref points to db.collection('average').doc('score') 
function createAverageAggregate(ref, num_shards) { 
    var batch = db.batch(); 

    // Initialize the counter document 
    batch.set(ref, { num_shards: num_shards }); 

    // Initialize each shard with count=0 
    for (let i = 0; i < num_shards; i++) { 
     let shardRef = ref.collection('shards').doc(i.toString()); 
     batch.set(shardRef, { count: 0, count: 0 }); 
    } 

    // Commit the write batch 
    return batch.commit(); 
} 

:あなたの更新コードがより合理化にするために

// average/score 
{ 
    "num_shards": NUM_SHARDS, 
    "shards": [subcollection] 
} 

// average/score/shards/${NUM} 
{ 
    "count": 115, 
    "score": 1472 
} 

、あなたが最初にこれらの破片を初期化することができますクラウド機能の平均アグリゲートは次のように簡単になりました。

// ref points to db.collection('average').doc('score') 
function updateAverage(db, ref, num_shards) { 
    // Select a shard of the counter at random 
    const shard_id = Math.floor(Math.random() * num_shards).toString(); 
    const shard_ref = ref.collection('shards').doc(shard_id); 

    // Update count in a transaction 
    return db.runTransaction(t => { 
     return t.get(shard_ref).then(doc => { 
      const new_count = doc.data().count + 1; 
      const new_score = doc.data().score + 1; 
      t.update(shard_ref, { count: new_count, score: new_score }); 
     }); 
    }); 
} 

Gあなたはこのシステムで達成することができます

// ref points to db.collection('average').doc('score') 
function getAverage(ref) { 
    // Sum the count and sum the score of each shard in the subcollection 
    return ref.collection('shards').get().then(snapshot => { 
     let total_count = 0; 
     let total_score = 0; 
     snapshot.forEach(doc => { 
      total_count += doc.data().count; 
      total_score += doc.data().score; 
     }); 
     return total_score/total_count; 
    }); 
} 

書き込み速度が毎秒NUM_SHARDSあるので、それに応じ計画:平均をettingすることは、その後に行うことができます。注:小さなものを始めて、簡単に破片の数を増やすことができます。 createAverageAggregateの新しいバージョンを作成して、最初に新しいものを初期化し、次にnum_shards設定を一致させるように更新して、断片の数を増やしてください。これはあなたのupdateAveragegetAverageの機能によって自動的に選択されます。

関連する問題