2017-10-03 16 views

답변

2

간단한 솔루션

당신은 대부분의 초에 한 번씩, 당신은 별도의 문서 average/score를 업데이트하는 클라우드 기능을 사용할 수있을 것입니다 기록되는 게임 결과의 수를 알고있는 경우. 각 게임 결과 추가에 대해 문서가없는 경우 count이라는 필드를 1로 설정하고 score이라는 필드를 게임 점수에 설정합니다. 문서가 존재하는 경우 count 필드에 1을 추가하고 score이라는 필드에 점수를 추가하십시오.

이제 평균 점수를 쿼리하려면 average/score을 읽고 scorecount으로 나누십시오. 당신이 의심되거나 초에 한 번씩 초과 기록되는 게임 결과의 수를 알고있는 경우

확장 가능한 솔루션

, 당신은 간단한 솔루션의 분산 카운터 스타일을 적용해야합니다.

하위 모음을 사용하여 모양을 평균 문서에 대한 데이터 모델 :

// 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 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(); 
} 

를 업데이트 클라우드 기능의 평균 집계는 다음과 같이 매우 쉽습니다.

// 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, 그래서 따라 계획 : 평균을 랩탑 설치하는 것은 다음 수행 할 수 있습니다. 참고 : 작은 것을 시작하고 쉽게 파편의 수를 늘릴 수 있습니다. createAverageAggregate의 새 버전을 작성하여 새 파일을 먼저 초기화 한 다음 sh_ad의 숫자를 늘린 다음 num_shards 설정을 일치하도록 업데이트하면됩니다. 이 내용은 updateAveragegetAverage 함수에 의해 자동으로 선택되어야합니다.