Toplu

Açıklama

aggregate aşaması, önceki aşamada döndürülen dokümanlardan toplu sonuçlar (ör. sayı, toplam) hesaplar.

İ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.

Söz dizimi

Group-by içermeyen toplamalarda 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şlemleri için 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 kalabalık ş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 da şu sonuçları verir:

{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 yapabilirsiniz.

Ö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ışı, Toplama İşlevleri ile ilgili özel sayfada bulunabilir.

Grup temel davranışları

Firestore, dokümanları 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 noktalı sayılar, decimal128 vb.) bağımsız olarak matematiksel olarak eşdeğer sayısal değerler gibi eşdeğer değerlerin tümünün birlikte gruplandırıldığı anlamına gelir.

Örneğin, numerics koleksiyonunda sırasıyla 32 bit tamsayı 1, 64 bit tamsayı 1L ve kayan noktalı sayı 1.0 değerlerini içeren farklı dokümanlar varsa bunların tümü aynı grupta toplanır.foo foo'ya göre gruplandırarak sayım 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ı tarafından uygun bir dizin seçilmediğinde toplama işleminin, bellekteki tüm grupları 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 bellek yetersizliği yaşanabilir.

Bu gibi durumlarda, veri kümesini toplama için sınırlandırmak üzere 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.