Birden çok alanda aralık ve eşitsizlik filtreleriyle sorguya genel bakış

Cloud Firestore, tek bir sorgudaki birden fazla alanda aralık ve eşitsizlik filtrelerinin kullanılmasını destekler. Birden fazla alanda aralık ve eşitsizlik koşulları belirleyebilir ve filtreleme sonrası mantığının uygulanmasını Cloud Firestore'e devrederek uygulama geliştirmenizi basitleştirebilirsiniz.

Birden fazla alanda aralık ve eşitsizlik filtreleri

Aşağıdaki sorgu, nüfusu 1.000.000'den fazla ve nüfus yoğunluğu alan birimi başına 10.000'den az olan tüm şehirleri döndürmek için nüfus ve yoğunlukla ilgili aralık filtreleri kullanır.

Modüler web sürümü 9

const q = query(
    collection(db, "cities"),
    where('population', '>', 1000000),
    where('density', '<', 10000),
  );

Swift

let query = db.collection("cities")
  .whereField("population", isGreaterThan: 1000000)
  .whereField("density", isLessThan: 10000)

Objective-C

FIRQuery *query =
 [[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
   queryWhereField:@"density" isLessThan:@10000];

Java Android

Query query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000);

Kotlin+KTX Android

val query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000)

Go

   query := client.Collection("cities").
      Where("population", ">", 1000000).
      Where("density", "<", 10000)

Java

db.collection("cities")
  .whereGreaterThan("population", 1000000)
  .whereLessThan("density", 10000);

Node.js

db.collection("cities")
  .where('population', '>', 1000000),
  .where('density', '<', 10000)

Python

from google.cloud import firestore

db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)

PHP

$collection = $db->collection('samples/php/cities');
$chainedQuery = $collection
    ->where('population', '>', 1000000)
    ->where('density', '<', 10000);

C#

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef
    .WhereGreaterThan("Population", 1000000)
    .WhereLessThan("Density", 10000);
QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
foreach (DocumentSnapshot documentSnapshot in querySnapshot)
{
    var name = documentSnapshot.GetValue<string>("Name");
    var population = documentSnapshot.GetValue<int>("Population");
    var density = documentSnapshot.GetValue<int>("Density");
    Console.WriteLine($"City '{name}' returned by query. Population={population}; Density={density}");
}

Ruby

query = cities_ref.where("population", ">", "1000000")
                  .where("density", "<", 10000)

C++

CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
                       .WhereLessThan("density", FieldValue::Integer(10000));

Unity

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
                      .WhereLessThan("density", 10000);

Dart

final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
                  .where("density", isLessThan: 10000);

Dizine eklemeyle ilgili dikkat edilmesi gereken noktalar

Sorgularınızı çalıştırmadan önce sorgular ve Cloud Firestore veri modeli hakkında bilgi edinin.

Cloud Firestore'te, bir sorgunun ORDER BY koşulu, sorguyu yayınlamak için hangi dizinlerin kullanılabileceğini belirler. Örneğin, bir ORDER BY a ASC, b ASC sorgusu için a ASC, b ASC alanlarında birleşik dizin gerekir.

Cloud Firestore sorgularının performansını ve maliyetini optimize etmek için dizindeki alanların sırasını optimize edin. Bunu yapmak için dizininizin, sorgunun gereksiz dizin girişlerinin taranmasını önleyen bir veri kümesine damıtılacak şekilde soldan sağa doğru sıralandığından emin olun.

Bir çalışan koleksiyonunda arama yapmak ve maaşı 100.000 ABD dolarından fazla olan ve deneyim yılı sayısı 0'dan fazla olan ABD'deki çalışanları bulmak istediğinizi varsayalım. Veri kümesi hakkındaki bilgileriniz doğrultusunda, maaş kısıtlamasının deneyim kısıtlamasından daha seçici olduğunu bilirsiniz. Dizin taramaları sayısını azaltacak ideal dizin (salary [...], experience [...]) olacaktır. Bu nedenle, hızlı ve uygun maliyetli olan sorgu, salary öğesini experience öğesinden önce sıralar ve aşağıdaki gibi görünür:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

Node.js

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .orderBy("salary")
  .orderBy("experience");

Python

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .order_by("salary")
  .order_by("experience");

Dizinleri optimize etmeyle ilgili en iyi uygulamalar

Dizinleri optimize ederken aşağıdaki en iyi uygulamalara dikkat edin.

Dizin alanlarını eşitliklere, ardından en seçici aralık veya eşitsizlik alanına göre sıralama

Cloud Firestore, orderBy() sorgusunun ilk alanındaki eşitlik kısıtlamalarını ve varsa aralık veya eşitsizlik kısıtlamasını karşılamak için bileşik dizinin en soldaki alanlarını kullanır. Bu kısıtlamalar, Cloud Firestore'ün taradığı dizin girişlerinin sayısını azaltabilir. Cloud Firestore, sorgunun diğer aralık veya eşitsizlik kısıtlamalarını karşılamak için dizinin kalan alanlarını kullanır. Bu kısıtlamalar, Cloud Firestore'ün taradığı dizin girişlerinin sayısını azaltmaz ancak eşleşmeyen belgeleri filtreleyerek istemcilere döndürülen belge sayısını azaltır.

Verimli dizinler oluşturma hakkında daha fazla bilgi için dizin mülkleri başlıklı makaleyi inceleyin.

Alanları, sorgu kısıtlaması seçiciliğine göre azalan düzende sıralama

Cloud Firestore'ün sorgunuz için en uygun dizini seçmesini sağlamak amacıyla, alanları sorgu kısıtlama seçiciliğine göre azalan düzende sıralayan bir orderBy() yan tümcesi belirtin. Daha yüksek seçicilik daha küçük bir doküman alt kümesiyle eşleşirken daha düşük seçicilik daha büyük bir doküman alt kümesiyle eşleşir. Dizin sıralamasında, seçtiğiniz aralık veya eşitsizlik alanlarının seçiciliğinin, daha düşük seçiciliğe sahip alanlara kıyasla daha yüksek olduğundan emin olun.

Cloud Firestore'ün ağ üzerinden taradığı ve döndürdüğü doküman sayısını en aza indirmek için alanları her zaman sorgu kısıtlama seçiciliğine göre azalan düzende sıralamanız gerekir. Sonuç kümesi gerekli sırada değilse ve sonuç kümesinin küçük olması bekleniyorsa sıralamayı beklentinize göre yeniden yapmak için istemci tarafı mantığı uygulayabilirsiniz.

Örneğin, maaşı 100.000 ABD dolarından fazla olan ABD'deki çalışanları bulmak için bir çalışan koleksiyonunda arama yapmak ve sonuçları çalışanın deneyim yılına göre sıralamak istediğinizi varsayalım. Yalnızca az sayıda çalışanın maaşlarının 100.000 ABD dolarından fazla olmasını bekliyorsanız sorguyu yazmanın en verimli yolu aşağıdaki gibidir:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .orderBy("salary")
  .get()
  .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
          // Order results by `experience`
        }
    });;

Node.js

const querySnapshot = await db.collection('employees')
                              .where("salary", ">", 100000)
                              .orderBy("salary")
                              .get();

// Order results by `experience`

Python

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

Sorguya experience üzerinde bir sıralama eklemek aynı belge grubunu döndürür ve sonuçları istemcilerde yeniden sıralamayı ortadan kaldırır. Ancak sorgu, önceki sorguya kıyasla çok daha fazla alakasız dizin girişi okuyabilir. Bunun nedeni, Cloud Firestore'ün her zaman dizin alanları ön ekinin sorgunun order by yan tümcesini eşleştirdiği bir dizini tercih etmesidir. experience, order by yan tümcesine eklenmişse Cloud Firestore, sorgu sonuçlarını hesaplamak için (experience [...], salary [...]) dizini seçer. experience üzerinde başka kısıtlama olmadığından Cloud Firestore, nihai sonuç kümesini bulmak için salary filtresini uygulamadan önce employees koleksiyonunun tüm dizin girişlerini okur. Bu, salary filtresini karşılamayan dizin girişlerinin yine de okunacağı ve böylece sorgunun gecikmesi ile maliyetinin artacağı anlamına gelir.

Fiyatlandırma

Birden fazla alanda aralık ve eşitsizlik filtreleri içeren sorgular, okunan dokümanlar ve dizin girişleri temel alınarak faturalandırılır.

Ayrıntılı bilgi için Fiyatlandırma sayfasını inceleyin.

Sınırlamalar

Sorgu sınırlamaları dışında, birden fazla alanda aralık ve eşitsizlik filtreleri içeren sorgular kullanmadan önce aşağıdaki sınırlamalara dikkat edin:

  • Belge alanlarında aralık veya eşitsizlik filtreleri ve belge anahtarı (__name__) üzerinde yalnızca eşitlik kısıtlamaları içeren sorgular desteklenmez.
  • Cloud Firestore, aralık veya eşitsizlik alanlarının sayısını 10 olarak sınırlandırır. Bu, sorguların çalıştırılmasının çok pahalı hale gelmesini önlemek içindir.

Sırada ne var?