내 앱은 score
이라는 필드에서 최종 스코어가 -30에서 +30까지의 게임 결과를 저장합니다. 모든 게임 결과의 전체 평균을 쿼리하려면 어떻게합니까?컬렉션에있는 모든 게임 결과의 평균 점수를 쿼리 하시겠습니까?
답변
간단한 솔루션
당신은 대부분의 초에 한 번씩, 당신은 별도의 문서 average/score
를 업데이트하는 클라우드 기능을 사용할 수있을 것입니다 기록되는 게임 결과의 수를 알고있는 경우. 각 게임 결과 추가에 대해 문서가없는 경우 count
이라는 필드를 1로 설정하고 score
이라는 필드를 게임 점수에 설정합니다. 문서가 존재하는 경우 count
필드에 1
을 추가하고 score
이라는 필드에 점수를 추가하십시오.
이제 평균 점수를 쿼리하려면 average/score
을 읽고 score
을 count
으로 나누십시오. 당신이 의심되거나 초에 한 번씩 초과 기록되는 게임 결과의 수를 알고있는 경우
확장 가능한 솔루션
, 당신은 간단한 솔루션의 분산 카운터 스타일을 적용해야합니다.
하위 모음을 사용하여 모양을 평균 문서에 대한 데이터 모델 :
// 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 설정을 일치하도록 업데이트하면됩니다. 이 내용은 updateAverage
및 getAverage
함수에 의해 자동으로 선택되어야합니다.