Açıklama
aggregate(...) aşamasında, önceki aşamada döndürülen dokümanlardan toplanan sonuçlar (ör. sayı, toplam) hesaplanır.
İsteğe bağlı olarak, gruplandırma ifadesi sağlandığında belgeler sağlanan ifadelere göre gruplandırılır ve ardından her gruba biriktirici işlevler uygulanır.
Örnekler
Group-by içermeyen toplama işlemleri için aggregate(...) aşaması bir veya daha fazla takma adlı toplama ifadesi alır:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate(
countAll().as("total"),
average("population").as("avg_population")
)
.execute();
Gruplandırma içeren toplama işlemlerinde, toplayıcıların yanı sıra ek gruplar gerekir:
Node.js
const result = await db.pipeline()
.collectionGroup('citites')
.aggregate({
accumulators: [
countAll().as('cities'),
field('population').sum().as('total_popoluation')
],
groups: [field('location.state').as('state')]
})
.execute();
Davranış
Gruplandırma Olmadan Toplamalar
Aşağıdaki belgeleri içeren bir cities koleksiyonu oluşturun:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA', population: 870000});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA', population: 8530000});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada', population: 2930000});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico', population: 9200000});
Toplam şehir sayısını ve ortalama nüfusunu öğrenmek için:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate(
countAll().as("total"),
average("population").as("avg_population")
)
.execute();
Bu durumda:
{avg_population: 5100000, total: 5}
Gruplarda Toplama İşlemleri Yapma
groups bağımsız değişkeni sağlayarak her bir farklı grupta toplama işlemleri gerçekleştirebilirsiniz.
Örneğin, her ülkedeki ve her eyaletteki en büyük nüfusa sahip şehri bulmak için:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [
countAll().as("number_of_cities"),
maximum("population").as("max_population")
],
groups: ["country", "state"]
})
.execute();
Bu sayede:
{country: "USA", state: "CA", max_population: 3970000, number_of_cities: 2},
{country: "USA", state: "NY", max_population: 8530000, number_of_cities: 1},
{country: "Canada", state: null, max_population: 2930000, number_of_cities: 1},
{country: "Mexico", state: null, max_population: 9200000, number_of_cities: 1}
Gruplandırmayla ilgili karmaşık ifadeler
aggregate(...) aşaması, yalnızca alan değerlerine göre gruplandırmanın yanı sıra karmaşık ifadelerin sonuçlarına göre gruplandırmayı da destekler. select(...) aşamasında geçerli olan tüm ifadeler gruplandırma anahtarı olarak kullanılabilir.
Bu sayede, hesaplanan değerlere veya koşullara göre esnek gruplandırma yapılabilir.
Örneğin, eyalet alanının boş olup olmadığına göre gruplandırmak ve her gruptaki toplam nüfusu öğrenmek için:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [
sum("population").as("total_population")
],
groups: [equal(field("state"), null).as("state_is_null")]
})
.execute();
şu sonucu döndürür:
{state_is_null: true, total_population: 12130000}
{state_is_null: false, total_population: 13370000}
Toplayıcı Davranışları
Desteklenen her işlevin (ör. count, sum, avg) toplama davranışını Toplama İşlevleri ile ilgili özel sayfada bulabilirsiniz.
Grup Anahtar Davranışları
Firestore, belgeleri gruplandırırken değerlerin aynı gruba ait olup olmadığını belirlemek için eşitlik semantiğini kullanır.
Bu, orijinal türden (32 bit tam sayı, 64 bit tam sayı, kayan nokta sayıları, decimal128 vb.) bağımsız olarak matematiksel olarak eşdeğer sayısal değerler gibi eşdeğer değerlerin hepsinin birlikte gruplandırıldığı anlamına gelir.
Örneğin, foo
sırasıyla 32 bit tam sayı 1, 64 bit tam sayı 1L ve kayan noktalı sayı 1.0 değerlerini
içeren farklı dokümanların bulunduğu bir koleksiyonda numerics, tüm bu değerler aynı grupta toplanır. foo ile gruplandırarak sayma işlemi yapıldığında şu sonuçlar döndürülür:
{foo: 1.0, count: 3}
Veri kümesinde farklı eşdeğer değerlerin bulunduğu bu gibi durumlarda, grubun çıkış değeri bu eşdeğer değerlerden herhangi biri olabilir.
Bu örnekte foo, 1, 1L veya 1.0 olabilir.
Belirleyici gibi görünse bile, belirli bir değerin seçilme davranışına güvenmeye çalışmamalısınız.
Bellek Kullanımı
Toplama işleminin nasıl yürütüleceği, kullanılabilir dizinlere bağlıdır. Sorgu optimizasyon aracı uygun bir dizin seçmediğinde toplama işleminin tüm grupları bellekte arabelleğe alması gerekir.
Çok sayıda grubun olması veya her grubun çok büyük olması (ör. büyük değerlere göre gruplandırma) durumunda bu aşamada yetersiz bellek oluşabilir.
Bu gibi durumlarda, üzerinde toplama yapılacak veri kümesini sınırlamak için filtreler uygulamanız, daha küçük/daha az alan üzerinde gruplandırma yapmanız veya büyük bellek kullanımlarını önlemek için önerildiği şekilde dizinler oluşturmanız gerekir. Sorgu Açıklama, hata ayıklamaya yardımcı olmak için gerçek sorgu yürütme planı ve profil oluşturma verileri hakkında bilgi sağlar.