Toplama sorgularıyla verileri özetleme

Toplama sorgusu, tek bir özet değeri döndürmek için birden fazla dizin girişinden gelen verileri işler.

Cloud Firestore, aşağıdaki toplama sorgularını destekler:

  • count()
  • sum()
  • average()

Cloud Firestore, toplamayı hesaplar ve yalnızca sonucu uygulamanıza geri iletir. Tam bir sorgu yürütmeye ve uygulamanızda toplamayı hesaplamaya kıyasla, toplama sorguları hem faturalandırılan belge okumaları hem de aktarılan baytlarda tasarruf sağlar.

Toplama sorguları, sorgularınızın halihazırda kullandığı mevcut dizin yapılandırmasına dayanır ve taranan dizin girişlerinin sayısıyla orantılı olarak ölçeklendirilir. Toplamadaki öğe sayısıyla birlikte gecikme de artar.

count() toplamasını kullanın

count() toplama sorgusu, bir koleksiyondaki veya sorgudaki belge sayısını belirlemenize olanak tanır.

Veri alma bölümünde oluşturduğumuz örnek verileri inceleyin.

Aşağıdaki count() toplaması, cities koleksiyonundaki şehirlerin toplam sayısını döndürür.

Web

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities")
let countQuery = query.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRCollectionReference *query = [self.db collectionWithPath:@"cities"];
[query.count aggregationWithSource:FIRAggregateSourceServer
                        completion:^(FIRAggregateQuerySnapshot *snapshot,
                                     NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching count: %@", error);
    } else {
        NSLog(@"Cities count: %@", snapshot.count);
    }
}];

Java

Query query = db.collection("cities");
AggregateQuery countQuery = query.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Count fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Count: " + snapshot.getCount());
        } else {
            Log.d(TAG, "Count failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Count fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Count: ${snapshot.count}")
    } else {
        Log.d(TAG, "Count failed: ", task.getException())
    }
}

Dart

// Returns number of documents in users collection
db.collection("users").count().get().then(
      (res) => print(res.count),
      onError: (e) => print("Error completing: $e"),
    );
Go
package firestore

import (
	"context"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
	firestorepb "cloud.google.com/go/firestore/apiv1/firestorepb"
)

func createCountQuery(w io.Writer, projectID string) error {

	// Instantiate the client
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return err
	}
	defer client.Close()

	collection := client.Collection("users")
	query := collection.Where("born", ">", 1850)

	// `alias` argument--"all"--provides a key for accessing the aggregate query
	// results. The alias value must be unique across all aggregation aliases in
	// an aggregation query and must conform to allowed Document field names.
	//
	// See https://cloud.google.com/firestore/docs/reference/rpc/google.firestore.v1#document for details.
	aggregationQuery := query.NewAggregationQuery().WithCount("all")
	results, err := aggregationQuery.Get(ctx)
	if err != nil {
		return err
	}

	count, ok := results["all"]
	if !ok {
		return errors.New("firestore: couldn't get alias for COUNT from results")
	}

	countValue := count.(*firestorepb.Value)
	fmt.Fprintf(w, "Number of results from query: %d\n", countValue.GetIntegerValue())
	return nil
}
Java
CollectionReference collection = db.collection("cities");
AggregateQuerySnapshot snapshot = collection.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
Node.js
const collectionRef = db.collection('cities');
const snapshot = await collectionRef.count().get();
console.log(snapshot.data().count);
      
Python
from google.cloud import firestore
from google.cloud.firestore_v1 import aggregation
from google.cloud.firestore_v1.base_query import FieldFilter


def create_count_query(project_id: str) -> None:
    """Builds an aggregate query that returns the number of results in the query.

    Arguments:
      project_id: your Google Cloud Project ID
    """
    client = firestore.Client(project=project_id)

    collection_ref = client.collection("users")
    query = collection_ref.where(filter=FieldFilter("born", ">", 1800))
    aggregate_query = aggregation.AggregationQuery(query)

    # `alias` to provides a key for accessing the aggregate query results
    aggregate_query.count(alias="all")

    results = aggregate_query.get()
    for result in results:
        print(f"Alias of results from query: {result[0].alias}")
        print(f"Number of results from query: {result[0].value}")

count() toplama işleminde sorgudaki tüm filtreler ve limit ifadeleri dikkate alınır.

Web

const coll = collection(db, "cities");
const q = query(coll, where("state", "==", "CA"));
const snapshot = await getCountFromServer(q);
console.log('count: ', snapshot.data().count);
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities").whereField("state", isEqualTo: "CA")
let countQuery = query.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query =
    [[self.db collectionWithPath:@"cities"]
                 queryWhereField:@"state"
                       isEqualTo:@"CA"];
[query.count aggregationWithSource:FIRAggregateSourceServer
                        completion:^(FIRAggregateQuerySnapshot *snapshot,
                                      NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching count: %@", error);
    } else {
        NSLog(@"Cities count: %@", snapshot.count);
    }
}];

Java

Query query = db.collection("cities").whereEqualTo("state", "CA");
AggregateQuery countQuery = query.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Count fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Count: " + snapshot.getCount());
        } else {
            Log.d(TAG, "Count failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities").whereEqualTo("state", "CA")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Count fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Count: ${snapshot.count}")
    } else {
        Log.d(TAG, "Count failed: ", task.getException())
    }
}

Dart

// This also works with collectionGroup queries.
db.collection("users").where("age", isGreaterThan: 10).count().get().then(
      (res) => print(res.count),
      onError: (e) => print("Error completing: $e"),
    );
Go
package firestore

import (
	"context"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
	firestorepb "cloud.google.com/go/firestore/apiv1/firestorepb"
)

func createCountQuery(w io.Writer, projectID string) error {

	// Instantiate the client
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return err
	}
	defer client.Close()

	collection := client.Collection("users")
	query := collection.Where("born", ">", 1850)

	// `alias` argument--"all"--provides a key for accessing the aggregate query
	// results. The alias value must be unique across all aggregation aliases in
	// an aggregation query and must conform to allowed Document field names.
	//
	// See https://cloud.google.com/firestore/docs/reference/rpc/google.firestore.v1#document for details.
	aggregationQuery := query.NewAggregationQuery().WithCount("all")
	results, err := aggregationQuery.Get(ctx)
	if err != nil {
		return err
	}

	count, ok := results["all"]
	if !ok {
		return errors.New("firestore: couldn't get alias for COUNT from results")
	}

	countValue := count.(*firestorepb.Value)
	fmt.Fprintf(w, "Number of results from query: %d\n", countValue.GetIntegerValue())
	return nil
}
Java
CollectionReference collection = db.collection("cities");
Query query = collection.whereEqualTo("state", "CA");
AggregateQuerySnapshot snapshot = query.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
Node.js
const collectionRef = db.collection('cities');
const query = collectionRef.where('state', '==', 'CA');
const snapshot = await query.count().get();
console.log(snapshot.data().count);
      
Python
from google.cloud import firestore
from google.cloud.firestore_v1 import aggregation
from google.cloud.firestore_v1.base_query import FieldFilter


def create_count_query(project_id: str) -> None:
    """Builds an aggregate query that returns the number of results in the query.

    Arguments:
      project_id: your Google Cloud Project ID
    """
    client = firestore.Client(project=project_id)

    collection_ref = client.collection("users")
    query = collection_ref.where(filter=FieldFilter("born", ">", 1800))
    aggregate_query = aggregation.AggregationQuery(query)

    # `alias` to provides a key for accessing the aggregate query results
    aggregate_query.count(alias="all")

    results = aggregate_query.get()
    for result in results:
        print(f"Alias of results from query: {result[0].alias}")
        print(f"Number of results from query: {result[0].value}")

sum() toplamasını kullanın

Belirli bir sorguyla eşleşen sayısal değerlerin toplamını döndürmek için sum() toplamasını kullanın. Örneğin:

Web

const coll = collection(firestore, 'cities');
const snapshot = await getAggregateFromServer(coll, {
  totalPopulation: sum('population')
});

console.log('totalPopulation: ', snapshot.data().totalPopulation);
    
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities")
let aggregateQuery = query.aggregate([AggregateField.sum("population")])
do {
  let snapshot = try await aggregateQuery.getAggregation(source: .server)
  print(snapshot.get(AggregateField.sum("population")))
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query = [self.db collectionWithPath:@"cities"];
FIRAggregateQuery *aggregateQuery = [query aggregate:@[
    [FIRAggregateField aggregateFieldForSumOfField:@"population"]]];
[aggregateQuery aggregationWithSource:FIRAggregateSourceServer
                           completion:^(FIRAggregateQuerySnapshot *snapshot,
                                        NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching aggregate: %@", error);
    } else {
        NSLog(@"Sum: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"population"]]);
    }
}];

Java

Query query = db.collection("cities");
AggregateQuery aggregateQuery = query.aggregate(AggregateField.sum("population"));
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Aggregate fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Sum: " + snapshot.get(AggregateField.sum("population")));
        } else {
            Log.d(TAG, "Aggregation failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities")
val aggregateQuery = query.aggregate(AggregateField.sum("population"))
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Aggregate fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Sum: ${snapshot.get(AggregateField.sum("population"))}")
    } else {
        Log.d(TAG, "Aggregate failed: ", task.getException())
    }
}
Java
collection = db.collection("cities");
snapshot = collection.aggregate(sum("population")).get().get();
System.out.println("Sum: " + snapshot.get(sum("population")));
      
Node.js
const coll = firestore.collection('cities');
const sumAggregateQuery = coll.aggregate({
         totalPopulation: AggregateField.sum('population'),
       });
  
const snapshot = await sumAggregateQuery.get();
console.log('totalPopulation: ', snapshot.data().totalPopulation);
      
Python
collection_ref = client.collection("users")
aggregate_query = aggregation.AggregationQuery(collection_ref)

aggregate_query.sum("coins", alias="sum")

results = aggregate_query.get()
for result in results:
    print(f"Alias of results from query: {result[0].alias}")
    print(f"Sum of results from query: {result[0].value}")
      
Go
func createSumQuery(w io.Writer, projectID string) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, projectID)
  if err != nil {
    return err
  }
  defer client.Close()

  collection := client.Collection("users")
  query := collection.Where("born", ">", 1850)

  aggregationQuery := query.NewAggregationQuery().WithSum("coins", "sum_coins")
  results, err := aggregationQuery.Get(ctx)
  if err != nil {
    return err
  }

  sum, ok := results["sum_coins"]
  if !ok {
    return errors.New("firestore: couldn't get alias for SUM from results")
  }

  sumValue := sum.(*firestorepb.Value)
  fmt.Fprintf(w, "Sum of results from query: %d\n", sumValue.GetIntegerValue())
  return nil
}
      

sum() toplama işleminde, sorgudaki tüm filtreler ve sınır ifadeleri dikkate alınır. Örneğin:

Web

const coll = collection(firestore, 'cities');
const q = query(coll, where('capital', '==', true));
const snapshot = await getAggregateFromServer(q, {
  totalPopulation: sum('population')
});

console.log('totalPopulation: ', snapshot.data().totalPopulation);
      
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities").whereField("capital", isEqualTo: true)
let aggregateQuery = query.aggregate([AggregateField.sum("population")])
do {
  let snapshot = try await aggregateQuery.getAggregation(source: .server)
  print(snapshot.get(AggregateField.sum("population")))
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query = [[self.db collectionWithPath:@"cities"]
                   queryWhereFilter:[FIRFilter filterWhereField:@"capital" isEqualTo:@YES]];
FIRAggregateQuery *aggregateQuery = [query aggregate:@[
    [FIRAggregateField aggregateFieldForSumOfField:@"population"]]];
[aggregateQuery aggregationWithSource:FIRAggregateSourceServer
                           completion:^(FIRAggregateQuerySnapshot *snapshot,
                                        NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching aggregate: %@", error);
    } else {
        NSLog(@"Sum: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"population"]]);
    }
}];

Java

Query query = db.collection("cities").whereEqualTo("capital", true);
AggregateQuery aggregateQuery = query.aggregate(AggregateField.sum("population"));
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Aggregate fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Sum: " + snapshot.get(AggregateField.sum("population")));
        } else {
            Log.d(TAG, "Aggregation failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities").whereEqualTo("capital", true)
val aggregateQuery = query.aggregate(AggregateField.sum("population"))
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Aggregate fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Sum: ${snapshot.get(AggregateField.sum("population"))}")
    } else {
        Log.d(TAG, "Aggregate failed: ", task.getException())
    }
}
Java
collection = db.collection("cities");
query = collection.whereEqualTo("state", "CA");
snapshot = query.aggregate(sum("population")).get().get();
System.out.println("Sum: " + snapshot.get(sum("population")));
      
Node.js
const coll = firestore.collection('cities');
const q = coll.where("capital", "==", true);
const sumAggregateQuery = q.aggregate({
        totalPopulation: AggregateField.sum('population'),
      });

const snapshot = await sumAggregateQuery.get();
console.log('totalPopulation: ', snapshot.data().totalPopulation);
      
Python
collection_ref = client.collection("users")
query = collection_ref.where(filter=FieldFilter("people", "==", "Matthew"))
aggregate_query = aggregation.AggregationQuery(query)

aggregate_query.sum("coins", alias="sum")

results = aggregate_query.get()
for result in results:
    print(f"Alias of results from query: {result[0].alias}")
    print(f"Sum of results from query: {result[0].value}")
      
Go
func createSumQuery(w io.Writer, projectID string) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, projectID)
  if err != nil {
    return err
  }
  defer client.Close()

  collection := client.Collection("users")
  query := collection.Where("born", ">", 1850).Limit(5)

  aggregationQuery := query.NewAggregationQuery().WithSum("coins", "sum_coins")
  results, err := aggregationQuery.Get(ctx)
  if err != nil {
    return err
  }

  sum, ok := results["sum_coins"]
  if !ok {
    return errors.New("firestore: couldn't get alias for SUM from results")
  }

  sumValue := sum.(*firestorepb.Value)
  fmt.Fprintf(w, "Sum of results from query: %d\n", sumValue.GetIntegerValue())
  return nil
}
      

average() toplamasını kullanın

Belirli bir sorguyla eşleşen sayısal değerlerin ortalamasını döndürmek için average() toplamasını kullanın. Örneğin:

Web

const coll = collection(firestore, 'cities');
const snapshot = await getAggregateFromServer(coll, {
  averagePopulation: average('population')
});

console.log('averagePopulation: ', snapshot.data().averagePopulation);
    
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities")
let aggregateQuery = query.aggregate([AggregateField.average("population")])
do {
  let snapshot = try await aggregateQuery.getAggregation(source: .server)
  print(snapshot.get(AggregateField.average("population")))
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query = [self.db collectionWithPath:@"cities"];
FIRAggregateQuery *aggregateQuery = [query aggregate:@[
    [FIRAggregateField aggregateFieldForAverageOfField:@"population"]]];
[aggregateQuery aggregationWithSource:FIRAggregateSourceServer
                           completion:^(FIRAggregateQuerySnapshot *snapshot,
                                        NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching aggregate: %@", error);
    } else {
        NSLog(@"Avg: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForAverageOfField:@"population"]]);
    }
}];

Java

Query query = db.collection("cities");
AggregateQuery aggregateQuery = query.aggregate(AggregateField.average("population"));
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Aggregate fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Average: " + snapshot.get(AggregateField.average("population")));
        } else {
            Log.d(TAG, "Aggregation failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities")
val aggregateQuery = query.aggregate(AggregateField.average("population"))
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Aggregate fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Average: ${snapshot.get(AggregateField.average("population"))}")
    } else {
        Log.d(TAG, "Aggregate failed: ", task.getException())
    }
}
Java
collection = db.collection("cities");
snapshot = collection.aggregate(average("population")).get().get();
System.out.println("Average: " + snapshot.get(average("population")));
      
Node.js
const coll = firestore.collection('cities');
const averageAggregateQuery = coll.aggregate({
        averagePopulation: AggregateField.average('population'),
      });

const snapshot = await averageAggregateQuery.get();
console.log('averagePopulation: ', snapshot.data().averagePopulation);
      
Python
collection_ref = client.collection("users")
aggregate_query = aggregation.AggregationQuery(collection_ref)

aggregate_query.avg("coins", alias="avg")

results = aggregate_query.get()
for result in results:
    print(f"Alias of results from query: {result[0].alias}")
    print(f"Average of results from query: {result[0].value}")
      
Go
func createAvgQuery(w io.Writer, projectID string) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, projectID)
  if err != nil {
          return err
  }
  defer client.Close()

  collection := client.Collection("users")
  query := collection.Where("born", ">", 1850)

  aggregationQuery := query.NewAggregationQuery().WithAvg("coins", "avg_coins")
  results, err := aggregationQuery.Get(ctx)
  if err != nil {
    return err
  }

  avg, ok := results["avg_coins"]
  if !ok {
    return errors.New("firestore: couldn't get alias for AVG from results")
  }

  avgValue := avg.(*firestorepb.Value)
  fmt.Fprintf(w, "Avg of results from query: %d\n", avgValue.GetDoubleValue())
  return nil
}
      

average() toplama işlemi, sorgudaki tüm filtreleri ve sınır yan tümcelerini dikkate alır. Örneğin:

Web

const coll = collection(firestore, 'cities');
const q = query(coll, where('capital', '==', true));
const snapshot = await getAggregateFromServer(q, {
  averagePopulation: average('population')
});

console.log('averagePopulation: ', snapshot.data().averagePopulation);
      
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities").whereField("capital", isEqualTo: true)
let aggregateQuery = query.aggregate([AggregateField.average("population")])
do {
  let snapshot = try await aggregateQuery.getAggregation(source: .server)
  print(snapshot.get(AggregateField.average("population")))
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query = [[self.db collectionWithPath:@"cities"]
                   queryWhereFilter:[FIRFilter filterWhereField:@"capital" isEqualTo:@YES]];
FIRAggregateQuery *aggregateQuery = [query aggregate:@[
    [FIRAggregateField aggregateFieldForAverageOfField:@"population"]]];
[aggregateQuery aggregationWithSource:FIRAggregateSourceServer
                           completion:^(FIRAggregateQuerySnapshot *snapshot,
                                        NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching aggregate: %@", error);
    } else {
        NSLog(@"Avg: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForAverageOfField:@"population"]]);
    }
}];

Java

Query query = db.collection("cities").whereEqualTo("capital", true);
AggregateQuery aggregateQuery = query.aggregate(AggregateField.average("population"));
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Aggregate fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Average: " + snapshot.get(AggregateField.average("population")));
        } else {
            Log.d(TAG, "Aggregation failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities").whereEqualTo("capital", true)
val aggregateQuery = query.aggregate(AggregateField.average("population"))
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Aggregate fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Average: ${snapshot.get(AggregateField.average("population"))}")
    } else {
        Log.d(TAG, "Aggregate failed: ", task.getException())
    }
}
Java
collection = db.collection("cities");
query = collection.whereEqualTo("state", "CA");
snapshot = query.aggregate(average("population")).get().get();
System.out.println("Average: " + snapshot.get(average("population")));
  
Node.js
const coll = firestore.collection('cities');
const q = coll.where("capital", "==", true);
const averageAggregateQuery = q.aggregate({
        averagePopulation: AggregateField.average('population'),
      });

const snapshot = await averageAggregateQuery.get();
console.log('averagePopulation: ', snapshot.data().averagePopulation);
      
Python
collection_ref = client.collection("users")
query = collection_ref.where(filter=FieldFilter("people", "==", "Matthew"))
aggregate_query = aggregation.AggregationQuery(query)

aggregate_query.avg("coins", alias="avg")

results = aggregate_query.get()
for result in results:
    print(f"Alias of results from query: {result[0].alias}")
    print(f"Average of results from query: {result[0].value}")
      
Go
func createAvgQuery(w io.Writer, projectID string) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, projectID)
  if err != nil {
        return err
  }
  defer client.Close()

  collection := client.Collection("users")
  query := collection.Where("born", ">", 1850).Limit(5)

  aggregationQuery := query.NewAggregationQuery().WithAvg("coins", "avg_coins")
  results, err := aggregationQuery.Get(ctx)
  if err != nil {
    return err
  }

  avg, ok := results["avg_coins"]
  if !ok {
    return errors.New("firestore: couldn't get alias for AVG from results")
  }

  avgValue := avg.(*firestorepb.Value)
  fmt.Fprintf(w, "Avg of results from query: %d\n", avgValue.GetDoubleValue())
  return nil
}
      

Bir sorgudaki birden çok toplamayı hesaplama

Birden fazla toplamayı tek bir toplama ardışık düzeninde birleştirebilirsiniz. Bu, gereken dizin okumalarının sayısını azaltabilir. Sorgu birden fazla alanda toplama içeriyorsa sorgu için bileşik dizin gerekebilir. Bu durumda Cloud Firestore bir dizin önerir.

Aşağıdaki örnek, tek bir toplama sorgusunda birden çok toplama işlemi gerçekleştirmektedir:

Web

const coll = collection(firestore, 'cities');
const snapshot = await getAggregateFromServer(coll, {
  countOfDocs: count(),
  totalPopulation: sum('population'),
  averagePopulation: average('population')
});

console.log('countOfDocs: ', snapshot.data().countOfDocs);
console.log('totalPopulation: ', snapshot.data().totalPopulation);
console.log('averagePopulation: ', snapshot.data().averagePopulation);
      
Swift
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
let query = db.collection("cities")
let aggregateQuery = query.aggregate([
  AggregateField.count(),
  AggregateField.sum("population"),
  AggregateField.average("population")])
do {
  let snapshot = try await aggregateQuery.getAggregation(source: .server)
  print("Count: \(snapshot.get(AggregateField.count()))")
  print("Sum: \(snapshot.get(AggregateField.sum("population")))")
  print("Average: \(snapshot.get(AggregateField.average("population")))")
} catch {
  print(error)
}
Objective-C
Not: Bu ürün, watchOS ve App Clip hedeflerinde kullanılamaz.
FIRQuery *query = [self.db collectionWithPath:@"cities"];
FIRAggregateQuery *aggregateQuery = [query aggregate:@[
    [FIRAggregateField aggregateFieldForCount],
    [FIRAggregateField aggregateFieldForSumOfField:@"population"],
    [FIRAggregateField aggregateFieldForAverageOfField:@"population"]]];
[aggregateQuery aggregationWithSource:FIRAggregateSourceServer
                           completion:^(FIRAggregateQuerySnapshot *snapshot,
                                        NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching aggregate: %@", error);
    } else {
        NSLog(@"Count: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]]);
        NSLog(@"Sum: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"population"]]);
        NSLog(@"Avg: %@", [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForAverageOfField:@"population"]]);
    }
}];

Java

Query query = db.collection("cities");
AggregateQuery aggregateQuery = query.aggregate(
        AggregateField.count(),
        AggregateField.sum("population"),
        AggregateField.average("population"));
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Aggregate fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Count: " + snapshot.get(AggregateField.count()));
            Log.d(TAG, "Sum: " + snapshot.get(AggregateField.sum("population")));
            Log.d(TAG, "Average: " + snapshot.get(AggregateField.average("population")));
        } else {
            Log.d(TAG, "Aggregation failed: ", task.getException());
        }
    }
});

Kotlin+KTX

val query = db.collection("cities")
val aggregateQuery = query.aggregate(
    AggregateField.count(),
    AggregateField.sum("population"),
    AggregateField.average("population")
)
aggregateQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Aggregate fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Count: ${snapshot.get(AggregateField.count())}")
        Log.d(TAG, "Sum: ${snapshot.get(AggregateField.sum("population"))}")
        Log.d(TAG, "Average: ${snapshot.get(AggregateField.average("population"))}")
    } else {
        Log.d(TAG, "Aggregate failed: ", task.getException())
    }
}
Java
collection = db.collection("cities");
query = collection.whereEqualTo("state", "CA");
AggregateQuery aggregateQuery = query.aggregate(count(), sum("population"), average("population"));
snapshot = aggregateQuery.get().get();
System.out.println("Count: " + snapshot.getCount());
System.out.println("Sum: " + snapshot.get(sum("population")));
System.out.println("Average: " + snapshot.get(average("population")));
    
Node.js
const coll = firestore.collection('cities');
const aggregateQuery = coll.aggregate({
    countOfDocs: AggregateField.count(),
    totalPopulation: AggregateField.sum('population'),
    averagePopulation: AggregateField.average('population')
  });

const snapshot = await aggregateQuery.get();
console.log('countOfDocs: ', snapshot.data().countOfDocs);
console.log('totalPopulation: ', snapshot.data().totalPopulation);
console.log('averagePopulation: ', snapshot.data().averagePopulation);
      
Python
collection_ref = client.collection("users")
query = collection_ref.where(filter=FieldFilter("people", "==", "Matthew"))
aggregate_query = aggregation.AggregationQuery(query)

aggregate_query.sum("coins", alias="sum").avg("coins", alias="avg")

results = aggregate_query.get()
for result in results:
    print(f"Alias of results from query: {result[0].alias}")
    print(f"Aggregation of results from query: {result[0].value}")
      
Go
func createMultiAggregationQuery(w io.Writer, projectID string) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, projectID)
  if err != nil {
    return err
  }
  defer client.Close()

  collection := client.Collection("users")
  query := collection.Where("born", ">", 1850)

  aggregationQuery := query.NewAggregationQuery().WithCount("count").WithSum("coins", "sum_coins").WithAvg("coins", "avg_coins")
  results, err := aggregationQuery.Get(ctx)
  if err != nil {
    return err
  }
}
      

Birden çok toplama içeren sorgular, yalnızca her toplamadaki tüm alanları içeren belgeleri içerir. Bu durum, her toplama işleminin ayrı ayrı yapılmasından farklı sonuçlar elde edilmesine yol açabilir.

Toplama sorguları için güvenlik kuralları

Cloud Firestore Güvenlik Kuralları, toplama sorgularında, belge döndüren sorgularla aynı şekilde çalışır. Diğer bir deyişle, yalnızca kurallarınız müşterilerin belirli toplama veya koleksiyon grubu sorgularını yürütmesine izin veriyorsa müşteriler toplama işlemini bu sorgularda da gerçekleştirebilir. Cloud Firestore Güvenlik Kurallarının sorgularla nasıl etkileşime girdiği hakkında daha fazla bilgi edinin.

Davranış ve sınırlamalar

Toplama sorgularıyla çalışırken aşağıdaki davranışa ve sınırlamalara dikkat edin:

  • Toplama sorgularını gerçek zamanlı dinleyiciler ve çevrimdışı sorgularla kullanamazsınız. Toplama sorguları yalnızca doğrudan sunucu yanıtı aracılığıyla desteklenir. Sorgular, yerel önbellek ve arabelleğe alınmış güncellemeler atlanarak yalnızca Cloud Firestore arka ucu tarafından sunulur. Bu davranış, Cloud Firestore işlemleri içinde gerçekleştirilen işlemlerle aynıdır.

  • Bir toplama 60 saniye içinde çözümlenemezse DEADLINE_EXCEEDED hatası döndürür. Performans, dizin yapılandırmanıza ve veri kümesinin boyutuna bağlıdır.

    İşlem, 60 saniyelik süre içinde tamamlanamazsa büyük veri kümeleri için sayaç kullanabilirsiniz.

  • Dizin girişlerinden okunan toplama sorguları yalnızca dizine eklenen alanları içerir.

  • Toplama sorgusuna OrderBy ifadesi eklediğinizde toplama işlemi, sıralama alanının bulunduğu belgelerle sınırlandırılır.

  • sum() ve average() toplamaları için sayısal olmayan değerler yoksayılır. sum() ve average() toplamaları, yalnızca tam sayı ve kayan noktalı sayı değerlerini dikkate alır.

  • Birden çok toplama işlemini tek bir sorguda birleştirirken sum() ve average() değerlerinin sayısal olmayan değerleri yoksaydığını, count() ise sayısal olmayan değerleri içerir.

  • Farklı alanlardaki toplamaları birleştirirseniz hesaplamaya yalnızca bu alanların tümünü içeren belgeler dahil edilir.

Fiyatlandırma

Toplama sorgularının fiyatlandırması, sorguyla eşleşen dizin girişlerinin sayısına bağlıdır. Çok sayıda eşleşen giriş için az sayıda okuma ücreti ödersiniz.

Daha ayrıntılı fiyatlandırma bilgilerine göz atın.