Arka plan
Ardışık düzen işlemleri, Cloud Firestore için gelişmiş sorgu işlevlerini ve karmaşık ifadeleri destekleyen yeni bir sorgu arayüzü sağlar. min(...), max(...), substring(...), regex_match(...) ve array_contains_all(...) gibi birçok yeni işlev ve karmaşık dönüşümler gerçekleştirebilmek için aşamalar sunar.
Başlarken
İstemci SDK'larını yüklemek ve ilk kullanıma hazırlamak için aşağıdaki kılavuzlardaki talimatlara bakın:
Söz dizimi
Aşağıdaki bölümlerde, ardışık düzen işlemlerinin söz dizimine genel bir bakış sunulmaktadır.
Kavramlar
Pipeline işlemlerindeki önemli bir fark, açık "aşama" sıralamasının kullanılmasıdır. Bu sayede daha karmaşık sorgular ifade edilebilir. Ancak bu, aşama sıralamasının ima edildiği temel işlemleri kullanan mevcut sorgu arayüzünden önemli bir sapmadır. Aşağıdaki Pipeline işlemleri örneğini inceleyin:
Web
const pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the // pipeline would have unintentional results. .limit(10);
Swift
let pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(Field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort([Field("name").ascending()]) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Kotlin
val pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Java
Pipeline pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10);
Python
from google.cloud.firestore_v1.pipeline_expressions import Field pipeline = ( client.pipeline() .collection("cities") .where(Field.of("population").greater_than(100_000)) .sort(Field.of("name").ascending()) .limit(10) )
Go
pipeline := client.Pipeline(). Collection("cities"). Where(firestore.FieldOf("population").GreaterThan(100000)). Sort(firestore.Orders(firestore.Ascending(firestore.FieldOf("name")))). Limit(10)
Başlatma
Ardışık düzen işlemleri, mevcut Cloud Firestore sorgularından gelen çok tanıdık bir söz dizimine sahiptir. Başlamak için aşağıdaki kodu yazarak bir sorgu başlatın:
Web
const { getFirestore } = require("firebase/firestore"); const { execute } = require("firebase/firestore/pipelines"); const database = getFirestore(app, "enterprise"); const pipeline = database.pipeline();
Swift
let firestore = Firestore.firestore(database: "enterprise") let pipeline = firestore.pipeline()
Kotlin
val firestore = Firebase.firestore("enterprise") val pipeline = firestore.pipeline()
Java
FirebaseFirestore firestore = FirebaseFirestore.getInstance("enterprise"); PipelineSource pipeline = firestore.pipeline();
Python
firestore_client = firestore.client(default_app, "your-new-enterprise-database") pipeline = firestore_client.pipeline()
Go
client, err := firestore.NewClientWithDatabase(ctx, projectID, databaseID) if err != nil { fmt.Fprintf(w, "firestore.NewClientWithDatabase failed: %v", err) return err } defer client.Close() pipeline := client.Pipeline().Collection("books")
Yapı
Ardışık düzen işlemleri oluştururken anlaşılması gereken birkaç terim vardır: aşamalar, ifadeler, işlevler ve alt sorgu sarmalayıcıları.

Aşamalar: Bir ardışık düzen bir veya daha fazla aşamadan oluşabilir. Mantıksal olarak bunlar, sorguyu yürütmek için gerçekleştirilen bir dizi adımı (veya aşamayı) temsil eder.
İfadeler: Aşamalar genellikle daha karmaşık sorguları ifade etmenize olanak tanıyan bir ifadeyi kabul eder. İfade basit olabilir ve eq("a", 1) gibi tek bir işlevden oluşabilir. and(eq("a", 1), eq("b", 2)). gibi ifadeleri iç içe yerleştirerek daha karmaşık ifadeler de oluşturabilirsiniz.
Alt sorgu sarmalayıcıları: array() ve scalar() gibi işlevler, iç içe yerleştirilmiş bir ardışık düzeni bir aşamada ifade olarak yerleştirmenize olanak tanır.
Alanlar / Sabitler / Değişkenler
Ardışık düzen işlemleri karmaşık ifadeleri destekler. Bu nedenle, bir değerin alan, sabit veya değişken olup olmadığını ayırt etmek önemlidir.
Alanlar, dokümanlardaki verilere atıfta bulunurken ve sabitler, bir ifadeye bağımsız değişken olarak herhangi bir değerin belirtilmesine olanak tanırken değişkenler, işlenen dokümanlar yerine sorgu yürütme kapsamındaki geçici değerlerin tanımlanmasına ve kullanılmasına olanak tanır. Aşağıda bu kavramlara genel bir bakış sunulmaktadır. Sorgu yürütme sırasında değişkenlerin nasıl okunacağı ve yazılacağı hakkında daha fazla bilgi için let(...) aşamasına bakın.
| Alanlar | Sabitler | Değişkenler | |
|---|---|---|---|
| Purpose | dokümanlardaki alanlara erişme veya alanları depolama | sabit bir değer belirtme | Ardışık düzen yürütme sırasında geçici değerler kullanma |
| SDK Kullanımı | field("name") |
constant("val") |
variable("name") |
| Kapsam | mevcut dokümana özel | dünya geneli | ardışık düzen ve alt ardışık düzenler için genel |
| Tanımlanmamış Referans | absent olarak değerlendirilir |
Yok | çalışma zamanı hatası oluşturur |
Örnekler:
Web
const pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Swift
let pipeline = db.pipeline() .collection("cities") .where(Field("name").equal(Constant("Toronto")))
Kotlin
val pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")))
Java
Pipeline pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Python
from google.cloud.firestore_v1.pipeline_expressions import Field, Constant pipeline = ( client.pipeline() .collection("cities") .where(Field.of("name").equal(Constant.of("Toronto"))) )
Go
pipeline := client.Pipeline().Collection("cities"). Where(firestore.FieldOf("name").Equal(firestore.ConstantOf("Toronto")))
Sahneler
Giriş aşamaları
Giriş aşaması, sorgunun ilk aşamasını temsil eder. Sorguladığınız ilk belge grubunu tanımlar. Pipeline işlemleri için bu, mevcut sorgulara büyük ölçüde benzerdir. Çoğu sorgu collection(...) veya collection_group(...) aşamasıyla başlar. İki yeni giriş aşaması database() ve documents(...)'dir. database(), veritabanındaki tüm belgelerin döndürülmesine olanak tanır. documents(...) ise toplu okuma ile aynı şekilde çalışır.
Web
let results; // Return all restaurants in San Francisco results = await execute(db.pipeline().collection("cities/sf/restaurants")); // Return all restaurants results = await execute(db.pipeline().collectionGroup("restaurants")); // Return all documents across all collections in the database (the entire database) results = await execute(db.pipeline().database()); // Batch read of 3 documents results = await execute(db.pipeline().documents([ doc(db, "cities", "SF"), doc(db, "cities", "DC"), doc(db, "cities", "NY") ]));
Swift
var results: Pipeline.Snapshot // Return all restaurants in San Francisco results = try await db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = try await db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = try await db.pipeline().database().execute() // Batch read of 3 documents results = try await db.pipeline().documents([ db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ]).execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute() // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute()
Java
Task<Pipeline.Snapshot> results; // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute(); // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute(); // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute(); // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute();
Python
# Return all restaurants in San Francisco results = client.pipeline().collection("cities/sf/restaurants").execute() # Return all restaurants results = client.pipeline().collection_group("restaurants").execute() # Return all documents across all collections in the database (the entire database) results = client.pipeline().database().execute() # Batch read of 3 documents results = ( client.pipeline() .documents( client.collection("cities").document("SF"), client.collection("cities").document("DC"), client.collection("cities").document("NY"), ) .execute() )
Go
// Return all restaurants in San Francisco results1, err := client.Pipeline().Collection("cities/sf/restaurants").Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } // Return all restaurants results2, err := client.Pipeline().CollectionGroup("restaurants").Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } // Return all documents across all collections in the database (the entire database) results3, err := client.Pipeline().Database().Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } // Batch read of 3 documents results4, err := client.Pipeline(). Documents([]*firestore.DocumentRef{ client.Collection("cities").Doc("SF"), client.Collection("cities").Doc("DC"), client.Collection("cities").Doc("NY"), }). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err }
Diğer tüm aşamalarda olduğu gibi bu giriş aşamalarından elde edilen sonuçların sırası da sabit değildir. Belirli bir sıralama gerekiyorsa her zaman sort(...) operatörü eklenmelidir.
Nerede
where(...) aşaması, önceki aşamada oluşturulan belgeler üzerinde standart bir filtre işlemi olarak işlev görür ve çoğunlukla mevcut sorgular için mevcut "where" söz dizimini yansıtır. Belirli bir ifadenin true dışında bir değer olarak değerlendirildiği tüm dokümanlar, döndürülen dokümanlardan filtrelenir.
Birden fazla where(...) ifadesi birbirine bağlanabilir ve and(...) ifadesi olarak işlev görebilir. Örneğin, aşağıdaki iki sorgu mantıksal olarak eşdeğerdir ve birbirinin yerine kullanılabilir.
Web
let results; results = await execute(db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) ); results = await execute(db.pipeline().collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) );
Swift
var results: Pipeline.Snapshot results = try await db.pipeline().collection("books") .where(Field("rating").equal(5)) .where(Field("published").lessThan(1900)) .execute() results = try await db.pipeline().collection("books") .where(Field("rating").equal(5) && Field("published").lessThan(1900)) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") .where(Expression.and(field("rating").equal(5), field("published").lessThan(1900))) .execute()
Java
Task<Pipeline.Snapshot> results; results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( field("rating").equal(5), field("published").lessThan(1900) )) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field results = ( client.pipeline() .collection("books") .where(Field.of("rating").equal(5)) .where(Field.of("published").less_than(1900)) .execute() ) results = ( client.pipeline() .collection("books") .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900))) .execute() )
Go
results1, err := client.Pipeline(). Collection("books"). Where(firestore.FieldOf("rating").Equal(5)). Where(firestore.FieldOf("published").LessThan(1900)). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } results2, err := client.Pipeline(). Collection("books"). Where(firestore.And( firestore.FieldOf("rating").Equal(5), firestore.FieldOf("published").LessThan(1900), )). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err }
Alanları Seçme / Ekleme ve Kaldırma
select(...),
add_fields(...) ve
remove_fields(...), önceki bir aşamadan döndürülen alanları değiştirmenize olanak tanır. Bu üçü genellikle projeksiyon tarzı
sahneler olarak adlandırılır.
select(...) ve add_fields(...), bir ifadenin sonucunu kullanıcı tarafından sağlanan bir alan adına belirtmenize olanak tanır. select(...) yalnızca belirtilen alan adlarına sahip dokümanları döndürürken add_fields(...), önceki aşamanın şemasını genişletir (aynı alan adlarına sahip değerlerin üzerine yazabilir).
remove_fields(...), önceki aşamadan kaldırılacak bir alan grubu belirtmenize olanak tanır. Mevcut olmayan alan adlarının belirtilmesi işlem yapılmamasına neden olur.
Aşağıdaki Döndürülecek Alanları Kısıtlama bölümüne bakın. Ancak genel olarak, sonucu yalnızca istemcide gereken alanlarla kısıtlamak için böyle bir aşama kullanmak, çoğu sorgunun maliyetini ve gecikmesini azaltmaya yardımcı olur.
Toplu / Farklı
aggregate(...) aşaması, giriş dokümanları üzerinde bir dizi toplama işlemi yapmanıza olanak tanır. Varsayılan olarak tüm dokümanlar birleştirilir ancak isteğe bağlı bir grouping bağımsız değişkeni sağlanarak giriş dokümanlarının farklı gruplarda birleştirilmesi sağlanabilir.
Web
const results = await execute(db.pipeline() .collection("books") .aggregate( field("rating").average().as("avg_rating") ) .distinct(field("genre")) );
Swift
let results = try await db.pipeline() .collection("books") .aggregate([ Field("rating").average().as("avg_rating") ], groups: [ Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .aggregate( AggregateStage .withAccumulators(AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre")) ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .aggregate(AggregateStage .withAccumulators( AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre"))) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .aggregate( Field.of("rating").average().as_("avg_rating"), groups=[Field.of("genre")] ) .execute() )
Go
snapshot := client.Pipeline(). Collection("books"). Aggregate( firestore.Accumulators(firestore.Average("rating").As("avg_rating")), firestore.WithAggregateGroups("genre"), ). Execute(ctx)
groupings belirtilmediğinde bu aşamada yalnızca tek bir doküman oluşturulur. Aksi takdirde, her benzersiz groupings değeri kombinasyonu için bir doküman oluşturulur.
distinct(...) aşaması, herhangi bir toplayıcı olmadan yalnızca benzersiz groupings oluşturmaya olanak tanıyan basitleştirilmiş bir toplama operatörüdür. Diğer tüm açılardan aggregate(...) ile aynı şekilde davranır. Aşağıdaki örnekte şunlar gösterilmektedir:
Web
const results = await execute(db.pipeline() .collection("books") .distinct( field("author").toUpper().as("author"), field("genre") ) );
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .distinct(Field.of("author").to_upper().as_("author"), "genre") .execute() )
Go
snapshot := client.Pipeline(). Collection("books"). Distinct(firestore.Fields( firestore.ToUpper(firestore.FieldOf("author")).As("author"), firestore.FieldOf("genre"), )). Execute(ctx)
İşlevler
İşlevler, ifadeler ve karmaşık sorgular oluşturmak için kullanılan bir yapı taşıdır. Örneklerle birlikte işlevlerin tam listesi için İşlevler referansı'na bakın. Tipik bir sorgunun yapısını kısaca hatırlayalım:

Birçok aşamada, bir veya daha fazla işlev içeren ifadeler kabul edilir. En yaygın işlev kullanımı, where(...) ve select(...) aşamalarında görülür. Bilmeniz gereken iki ana işlev türü vardır:
Web
let results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = await execute(db.pipeline().collection("books") .select(field("current").logicalMinimum(field("updated")).as("price_min")) ); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = await execute(db.pipeline().collection("books") .aggregate(field("price").minimum().as("min_price")) );
Swift
var results: Pipeline.Snapshot // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = try await db.pipeline().collection("books") .select([ Field("current").logicalMinimum(["updated"]).as("price_min") ]) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = try await db.pipeline().collection("books") .aggregate([Field("price").minimum().as("min_price")]) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute()
Java
Task<Pipeline.Snapshot> results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute(); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field # Type 1: Scalar (for use in non-aggregation stages) # Example: Return the min store price for each book. results = ( client.pipeline() .collection("books") .select( Field.of("current").logical_minimum(Field.of("updated")).as_("price_min") ) .execute() ) # Type 2: Aggregation (for use in aggregate stages) # Example: Return the min price of all books. results = ( client.pipeline() .collection("books") .aggregate(Field.of("price").minimum().as_("min_price")) .execute() )
Go
// Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results1, err := client.Pipeline(). Collection("books"). Select(firestore.Fields( firestore.LogicalMinimum(firestore.FieldOf("current"), firestore.FieldOf("updated")).As("price_min"), )). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err } // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results2, err := client.Pipeline(). Collection("books"). Aggregate(firestore.Accumulators( firestore.Minimum("price").As("min_price"), )). Execute(ctx).Results().GetAll() if err != nil { fmt.Fprintf(w, "GetAll failed: %v", err) return err }
Sınırlar
Enterprise sürümü, sorgunun şekli konusunda genellikle herhangi bir sınırlama getirmez. Başka bir deyişle, IN veya OR sorgusunda az sayıda değerle sınırlı değilsiniz. Bunun yerine, dikkat etmeniz gereken iki temel sınır vardır:
- Son tarih: 60 saniye (Standard sürümle aynı).
- Bellek kullanımı: Sorgu yürütme sırasında somutlaştırılan veri miktarı için 128 MiB sınırı.
Hatalar
Sorguların başarısız olmasının birkaç nedeni olabilir. Sık karşılaşılan hatalar ve bu hatalarla ilgili yapabileceğiniz işlemlerin bağlantısını aşağıda bulabilirsiniz:
| Hata Kodu | İşlem |
DEADLINE_EXCEEDED
|
Yürüttüğünüz sorgu 60 saniyelik süreyi aşıyor ve ek optimizasyon gerektiriyor. İpuçları için performans bölümüne bakın. Sorunun temel nedenini bulamıyorsanız ekiple iletişime geçin. |
RESOURCE_EXHAUSTED
|
Yürüttüğünüz sorgu, bellek sınırlarını aşıyor ve ek optimizasyon gerektiriyor. İpuçları için performans bölümüne bakın. Sorunun temel nedenini bulamıyorsanız ekiple iletişime geçin. |
INTERNAL
|
Destek için ekiple iletişime geçin. |
Performans
Enterprise sürümü veritabanlarında her zaman bir dizin bulunması gerekmez.
Bu, bir sorgunun, FAILED_PRECONDITION eksik dizin hatasıyla hemen başarısız olan mevcut sorgulara kıyasla daha yüksek gecikme gösterebileceği anlamına gelir. Pipeline işlemlerinin performansını artırmak için uygulayabileceğiniz birkaç adım vardır.
Dizin oluşturma
Kullanılan Dizin
Sorgu açıklaması, sorgunuzun bir dizin tarafından mı sunulduğunu yoksa tablo taraması gibi daha az verimli bir işleme mi geri döndüğünü belirlemenize olanak tanır. Sorgunuz bir dizinden tam olarak sunulmuyorsa talimatları uygulayarak dizin oluşturabilirsiniz.
Dizin oluşturma
Dizin oluşturmak için mevcut dizin yönetimi belgelerini inceleyebilirsiniz. Dizin oluşturmadan önce Cloud Firestore uygulamasındaki dizinlerle ilgili genel en iyi uygulamaları öğrenin. Sorgunuzun dizinlerden yararlanabilmesi için aşağıdaki sırayla alanlar içeren dizinler oluşturmak üzere en iyi uygulamaları izleyin:
- Eşitlik filtrelerinde kullanılacak tüm alanlar (herhangi bir sırada)
- Sıralanacak tüm alanlar (aynı sırada)
- Sorgu kısıtlaması seçiciliğinin azalan sırasına göre aralık veya eşitsizlik filtrelerinde kullanılacak alanlar
Örneğin, aşağıdaki sorgu için:
Web
const results = await execute(db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("published").lessThan(1900)) .where(Field("genre").equal("Science Fiction")) .where(Field("rating").greaterThan(4.3)) .sort([Field("published").descending()]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("published").less_than(1900)) .where(Field.of("genre").equal("Science Fiction")) .where(Field.of("rating").greater_than(4.3)) .sort(Field.of("published").descending()) .execute() )
Go
snapshot := client.Pipeline(). Collection("books"). Where(firestore.FieldOf("published").LessThan(1900)). Where(firestore.FieldOf("genre").Equal("Science Fiction")). Where(firestore.FieldOf("rating").GreaterThan(4.3)). Sort(firestore.Orders(firestore.Descending(firestore.FieldOf("published")))). Execute(ctx)
Önerilen dizin, (genre [...], published DESC, avg_rating DESC). için books üzerinde bir koleksiyon kapsamı dizinidir.
Dizin yoğunluğu
Cloud Firestore, seyrek ve seyrek olmayan dizinleri destekler. Daha fazla bilgi için Dizin yoğunluğu konusuna bakın.
Kapsanan Sorgular ve İkincil Dizinler
Döndürülen tüm alanlar ikincil bir dizinde mevcutsa Cloud Firestore, dokümanın tamamını getirmeyi atlayabilir ve yalnızca dizinden sonuçları döndürebilir. Bu genellikle gecikme süresinde (ve maliyette) önemli bir iyileşme sağlar. Aşağıdaki örnek sorguyu kullanarak:
Web
const results = await execute(db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("category").like("%fantasy%")) .where(Field("title").exists()) .where(Field("author").exists()) .select([Field("title"), Field("author")]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("category").like("%fantasy%")) .where(Field.of("title").exists()) .where(Field.of("author").exists()) .select("title", "author") .execute() )
Go
snapshot := client.Pipeline(). Collection("books"). Where(firestore.FieldOf("category").Like("%fantasy%")). Where(firestore.FieldOf("title").FieldExists()). Where(firestore.FieldOf("author").FieldExists()). Select(firestore.Fields("title", "author")). Execute(ctx)
Veritabanında (category [...], title [...], author [...]) için books üzerinde bir koleksiyon kapsamı dizini varsa ana dokümanlardan herhangi bir şey getirmesi gerekmez. Bu durumda dizindeki sıra önemli değildir. [...] bunu belirtmek için kullanılır.
Döndürülecek alanları kısıtlama
Varsayılan olarak, Cloud Firestore sorgusu bir dokümandaki tüm alanları döndürür.
Bu, ilişkisel sistemlerdeki SELECT * sorgusuna benzer. Ancak uygulamanız alanların yalnızca bir alt kümesine ihtiyaç duyuyorsa bu filtrelemeyi sunucu tarafına aktarmak için select(...) veya restrict(...) aşamaları kullanılabilir. Bu, hem yanıt boyutunu azaltır (ağ çıkış maliyetini azaltır) hem de gecikmeyi iyileştirir.
Sorun Giderme Araçları
Sorgu Açıklaması
Query Explain, yürütme metriklerini ve kullanılan dizinlerle ilgili ayrıntıları görünür hale getirmenize olanak tanır.
Metrikler
Mevcut Cloud Firestore metrikleriyle tam olarak entegre edilmiş ardışık düzen işlemleri.
Bilinen Sorunlar / Sınırlamalar
Özel Dizinler
Ardışık düzen işlemleri henüz mevcut array-contains ve vector dizin türlerini desteklemiyor. Cloud Firestore, bu tür sorguları reddetmek yerine mevcut diğer ascending ve descending dizinlerini kullanmaya çalışır. Bu nedenle, array_contains veya find_nearest ifadelerinin mevcut eşdeğerlerinden daha yavaş olması beklenir.
Gerçek Zamanlı ve Çevrimdışı Destek
Ardışık düzen işlemlerinde gerçek zamanlı ve çevrimdışı özellikler yoktur.
Sırada ne var?
- İşlevler ve aşamalar referans belgelerini incelemeye başlayın.
- Alt sorgularla birleştirme işlemlerini nasıl yapacağınızı öğrenin.