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

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

Birden fazla alanda aralık ve eşitsizlik filtreleri

Aşağıdaki sorgu, nüfusun 1.000.000'dan fazla ve nüfus yoğunluğunun birim alan başına 10.000'den az olduğu tüm şehirleri döndürmek için nüfus ve yoğunluk üzerinde aralık filtreleri kullanır.

Web sürümü 9 modüler

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 ekleme ile ilgili dikkat edilmesi gereken noktalar

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

Cloud Firestore içinde, bir sorgunun ORDER BY koşulu, sorguya hizmet etmek 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 soldan sağa doğru sıralandığından emin olun. Böylece sorgu, gereksiz dizin girişlerinin taranmasını engelleyen bir veri kümesine dönüştürülür.

Bir çalışan koleksiyonunda arama yapmak ve maaşı 100.000 ABD dolarından fazla olan ve deneyim süresi 0'dan fazla olan ABD'deki çalışanları bulmak istediğinizi varsayalım. Veri kümesiyle ilgili bilgilerinizden yola çıkarak maaş kısıtlamasının deneyim kısıtlamasından daha seçici olduğunu biliyorsunuz. Dizin taramalarının sayısını azaltacak ideal dizin (salary [...], experience [...]) olurdu. Bu nedenle, hızlı ve uygun maliyetli sorgu, salary öğesini experience öğesinden önce sıralar ve şu şekilde 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 göre, ardından en seçici aralığa veya eşitsizlik alanına göre sıralayın.

Cloud Firestore, eşitlik kısıtlamalarını ve varsa orderBy() sorgusunun ilk alanındaki 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 tarafından taranan 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 tarafından taranan 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 özellikleri başlıklı makaleyi inceleyin.

Alanları sorgu kısıtlaması seçiciliğine göre azalan sırada düzenleyin.

Cloud Firestore'nın sorgunuz için en uygun dizini seçmesini sağlamak amacıyla, alanları sorgu kısıtlaması seçiciliğinin azalan sırasına göre sıralayan bir orderBy() ifadesi belirtin. Daha yüksek seçicilik, daha küçük bir belge alt kümesiyle eşleşirken daha düşük seçicilik, daha büyük bir belge alt kümesiyle eşleşir. Daha yüksek seçiciliğe sahip aralık veya eşitsizlik alanlarını, daha düşük seçiciliğe sahip alanlardan önce dizin sıralamasında seçtiğinizden emin olun.

Cloud Firestore'nın ağ üzerinden taradığı ve döndürdüğü doküman sayısını en aza indirmek için alanları her zaman sorgu kısıtlaması seçiciliğinin azalan sırasına göre sıralamanız gerekir. Sonuç kümesi gerekli sırada değilse ve sonuç kümesinin küçük olması bekleniyorsa sıralama beklentinize göre yeniden sıralamak 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şının 100.000 ABD dolarından fazla olacağını düşünüyorsanız sorguyu yazmanın en verimli yolu şudur:

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 sıralama eklemek aynı belge grubunu döndürür ve sonuçların istemcilerde yeniden sıralanmasını önler. Ancak sorgu, önceki sorguya kıyasla çok daha fazla gereksiz dizin girişi okuyabilir. Bunun nedeni, Cloud Firestore'nın her zaman sorgunun order by ifadesiyle önek eşleşmesi olan bir dizini tercih etmesidir. Sıralama ölçütü yan tümcesine experience eklenirse Cloud Firestore, sorgu sonuçlarını hesaplamak için (experience [...], salary [...]) dizinini seçer. experience üzerinde başka kısıtlama olmadığından, Cloud Firestore, son sonuç kümesini bulmak için salary filtresini uygulamadan önce employees koleksiyonunun tüm dizin girişlerini okur. Bu, salary filtreyi karşılamayan dizin girişlerinin yine de okunacağı, dolayısıyla sorgunun gecikme süresinin ve maliyetinin artacağı anlamına gelir.

Fiyatlandırma

Birden fazla alanda aralık ve eşitsizlik filtreleri içeren sorgular, okunan dokümanlara ve okunan dizin girişlerine göre faturalandırılır.

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

Sınırlamalar

Sorgu sınırlamalarının yanı sıra, birden fazla alanda aralık ve eşitsizlik filtreleriyle sorgu kullanmadan önce aşağıdaki sınırlamalara dikkat edin:

  • Belge alanlarında aralık veya eşitsizlik filtreleri içeren ve yalnızca belge anahtarında eşitlik kısıtlamaları (__name__) olan sorgular desteklenmez.
  • Cloud Firestore, aralık veya eşitsizlik alanlarının sayısını 10 ile sınırlar. Bu sınırlama, sorguların çalıştırılamayacak kadar pahalı olmasını önlemek amacıyla düşünülmüştür.

Sırada ne var?