Veri Alma

Bu belge, veritabanı verilerini almanın temellerini, verilerin nasıl sıralandığını ve veriler üzerinde basit sorguların nasıl gerçekleştirileceğini kapsar. Yönetici SDK'sındaki veri alma, farklı programlama dillerinde biraz farklı şekilde uygulanır.

  1. Zaman uyumsuz dinleyiciler: Bir Firebase Gerçek Zamanlı Veritabanında depolanan veriler, bir veritabanı referansına zaman uyumsuz bir dinleyici eklenerek alınır. Dinleyici, verilerin ilk durumu için bir kez ve veriler değiştiğinde yeniden tetiklenir. Bir olay dinleyicisi birkaç farklı olay türü alabilir. Bu veri alma modu Java, Node.js ve Python Admin SDK'larında desteklenir.
  2. Okumaları engelleme: Bir Firebase Gerçek Zamanlı Veritabanında depolanan veriler, referansta depolanan verileri döndüren bir veritabanı referansında bir engelleme yöntemi çağrılarak alınır. Her yöntem çağrısı bir kerelik bir işlemdir. Bu, SDK'nın sonraki veri güncellemelerini dinleyen herhangi bir geri arama kaydetmediği anlamına gelir. Bu veri alma modeli Python ve Go Admin SDK'larında desteklenir.

Başlarken

Bir Firebase veritabanından verilerin nasıl okunacağını anlamak için önceki makaledeki blog örneğini tekrar gözden geçirelim. Örnek uygulamadaki blog gönderilerinin https://docs-examples.firebaseio.com/server/saving-data/fireblog/posts.json veritabanı URL'sinde depolandığını hatırlayın. Gönderi verilerinizi okumak için aşağıdakileri yapabilirsiniz:

Java
public static class Post {

  public String author;
  public String title;

  public Post(String author, String title) {
    // ...
  }

}

// Get a reference to our posts
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/fireblog/posts");

// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    Post post = dataSnapshot.getValue(Post.class);
    System.out.println(post);
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    System.out.println("The read failed: " + databaseError.getCode());
  }
});
Node.js
// Get a database reference to our posts
const db = getDatabase();
const ref = db.ref('server/saving-data/fireblog/posts');

// Attach an asynchronous callback to read the data at our posts reference
ref.on('value', (snapshot) => {
  console.log(snapshot.val());
}, (errorObject) => {
  console.log('The read failed: ' + errorObject.name);
}); 
piton
# Import database module.
from firebase_admin import db

# Get a database reference to our posts
ref = db.reference('server/saving-data/fireblog/posts')

# Read the data at the posts reference (this is a blocking operation)
print(ref.get())
Gitmek

// Post is a json-serializable type.
type Post struct {
	Author string `json:"author,omitempty"`
	Title  string `json:"title,omitempty"`
}

// Create a database client from App.
client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// Get a database reference to our posts
ref := client.NewRef("server/saving-data/fireblog/posts")

// Read the data at the posts reference (this is a blocking operation)
var post Post
if err := ref.Get(ctx, &post); err != nil {
	log.Fatalln("Error reading value:", err)
}

Yukarıdaki kodu çalıştırırsanız, konsola kaydedilen tüm gönderilerinizi içeren bir nesne göreceksiniz. Node.js ve Java söz konusu olduğunda, veritabanı referansınıza her yeni veri eklendiğinde dinleyici işlevi çağrılır ve bunun gerçekleşmesi için herhangi bir ekstra kod yazmanız gerekmez.

Java ve Node.js'de geri arama işlevi, verilerin anlık görüntüsü olan bir DataSnapshot alır. Anlık görüntü, zaman içinde tek bir noktada belirli bir veritabanı referansındaki verilerin bir resmidir. Bir anlık görüntüde val() / getValue() çağrılması, verilerin dile özgü nesne temsilini döndürür. Başvurunun konumunda hiçbir veri yoksa, anlık görüntünün değeri null olur. Python'daki get() yöntemi, verilerin doğrudan bir Python temsilini döndürür. Go'daki Get() işlevi, verileri belirli bir veri yapısında sıralar.

Yukarıdaki örnekte, yalnızca bir veri parçası değişse bile bir Firebase veritabanı referansının tüm içeriğini okuyan value olay türünü kullandığımıza dikkat edin. value , veritabanından veri okumak için kullanabileceğiniz aşağıda listelenen beş farklı olay türünden biridir.

Java ve Node.js'de Olay Türlerini Okuyun

Değer

value olayı, read olayı sırasında var oldukları gibi, belirli bir veritabanı yolundaki içeriğin statik bir anlık görüntüsünü okumak için kullanılır. İlk verilerle bir kez ve veriler her değiştiğinde tekrar tetiklenir. Olay geri araması, alt veriler de dahil olmak üzere o konumdaki tüm verileri içeren bir anlık görüntüye iletilir. Yukarıdaki kod örneğinde value , uygulamanızdaki tüm blog gönderilerini döndürdü. Her yeni blog yazısı eklendiğinde, geri arama işlevi tüm yazıları döndürür.

Çocuk Eklendi

child_added olayı genellikle veritabanından bir öğe listesi alınırken kullanılır. Konumun tüm içeriğini döndüren value farklı olarak, child_added , mevcut her alt öğe için bir kez tetiklenir ve ardından belirtilen yola her yeni bir alt öğe eklendiğinde yeniden tetiklenir. Olay geri çağrısı, yeni alt öğenin verilerini içeren bir anlık görüntüye iletilir. Sıralama amacıyla, önceki çocuğun anahtarını içeren ikinci bir argüman da iletilir.

Yalnızca blog uygulamanıza eklenen her yeni gönderideki verileri almak istiyorsanız, child_added kullanabilirsiniz:

Java
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    Post newPost = dataSnapshot.getValue(Post.class);
    System.out.println("Author: " + newPost.author);
    System.out.println("Title: " + newPost.title);
    System.out.println("Previous Post ID: " + prevChildKey);
  }

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {}

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Retrieve new posts as they are added to our database
ref.on('child_added', (snapshot, prevChildKey) => {
  const newPost = snapshot.val();
  console.log('Author: ' + newPost.author);
  console.log('Title: ' + newPost.title);
  console.log('Previous Post ID: ' + prevChildKey);
});

Bu örnekte anlık görüntü, bireysel bir blog gönderisine sahip bir nesne içerecektir. SDK, değeri alarak gönderileri nesnelere dönüştürdüğü için, sırasıyla author ve title çağırarak gönderinin yazar ve başlık özelliklerine erişebilirsiniz. Ayrıca, ikinci prevChildKey bağımsız değişkeninden önceki gönderi kimliğine de erişebilirsiniz.

Çocuk Değiştirildi

child_changed olayı, bir alt düğüm her değiştirildiğinde tetiklenir. Bu, alt düğümün alt öğelerinde yapılan tüm değişiklikleri içerir. Genellikle bir öğe listesindeki değişikliklere yanıt vermek için child_added ve child_removed ile birlikte kullanılır. Olay geri çağrısına geçirilen anlık görüntü, alt öğe için güncellenmiş verileri içerir.

Blog gönderileri düzenlendiklerinde güncellenmiş verileri okumak için child_changed kullanabilirsiniz:

Java
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
    Post changedPost = dataSnapshot.getValue(Post.class);
    System.out.println("The updated post title is: " + changedPost.title);
  }

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {}

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Get the data on a post that has changed
ref.on('child_changed', (snapshot) => {
  const changedPost = snapshot.val();
  console.log('The updated post title is ' + changedPost.title);
});

Çocuk Kaldırıldı

child_removed olayı, acil bir çocuk kaldırıldığında tetiklenir. Genellikle child_added ve child_changed ile birlikte kullanılır. Olay geri çağrısına geçirilen anlık görüntü, kaldırılan alt öğenin verilerini içerir.

Blog örneğinde, konsola silinen gönderi hakkında bir bildirim kaydetmek için child_removed kullanabilirsiniz:

Java
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {
    Post removedPost = dataSnapshot.getValue(Post.class);
    System.out.println("The blog post titled " + removedPost.title + " has been deleted");
  }

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Get a reference to our posts
const ref = db.ref('server/saving-data/fireblog/posts');

// Get the data on a post that has been removed
ref.on('child_removed', (snapshot) => {
  const deletedPost = snapshot.val();
  console.log('The blog post titled \'' + deletedPost.title + '\' has been deleted');
});

çocuk taşındı

child_moved olayı, sonraki bölümde ele alınan sıralı verilerle çalışırken kullanılır.

Etkinlik Garantileri

Firebase veritabanı, olaylarla ilgili birkaç önemli garanti verir:

Veritabanı Olay Garantileri
Yerel durum değiştiğinde olaylar her zaman tetiklenir.
Yerel işlemler veya zamanlamanın geçici ağ bağlantısı kaybı gibi geçici farklılıklara neden olduğu durumlarda bile, olaylar her zaman sonunda verilerin doğru durumunu yansıtacaktır.
Tek bir istemciden gelen yazmalar her zaman sunucuya yazılır ve sırayla diğer kullanıcılara yayınlanır.
Değer olayları her zaman en son tetiklenir ve o anlık görüntü alınmadan önce meydana gelen diğer olaylardan güncellemeleri içermesi garanti edilir.

Değer olayları her zaman en son tetiklendiğinden, aşağıdaki örnek her zaman işe yarar:

Java
final AtomicInteger count = new AtomicInteger();

ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    // New child added, increment count
    int newCount = count.incrementAndGet();
    System.out.println("Added " + dataSnapshot.getKey() + ", count is " + newCount);
  }

  // ...
});

// The number of children will always be equal to 'count' since the value of
// the dataSnapshot here will include every child_added event triggered before this point.
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    long numChildren = dataSnapshot.getChildrenCount();
    System.out.println(count.get() + " == " + numChildren);
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
let count = 0;

ref.on('child_added', (snap) => {
  count++;
  console.log('added:', snap.key);
});

// length will always equal count, since snap.val() will include every child_added event
// triggered before this point
ref.once('value', (snap) => {
  console.log('initial data loaded!', snap.numChildren() === count);
});

Geri Aramaları Ayırmak

Geri aramalar, aşağıdaki gibi, kaldırılacak olay türü ve kaldırılacak geri arama işlevi belirtilerek kaldırılır:

Java
// Create and attach listener
ValueEventListener listener = new ValueEventListener() {
    // ...
};
ref.addValueEventListener(listener);

// Remove listener
ref.removeEventListener(listener);
Node.js
ref.off('value', originalCallback);

on() içine bir kapsam bağlamı ilettiyseniz, geri arama ayrılırken iletilmelidir:

Java
// Not applicable for Java
Node.js
ref.off('value', originalCallback, ctx);

Bir konumdaki tüm geri aramaları kaldırmak isterseniz aşağıdakileri yapabilirsiniz:

Java
// No Java equivalent, listeners must be removed individually.
Node.js
// Remove all value callbacks
ref.off('value');

// Remove all callbacks of any type
ref.off();

Verileri Bir Kez Okumak

Bazı durumlarda, bir geri aramanın bir kez çağrılması ve ardından hemen kaldırılması yararlı olabilir. Bunu kolaylaştırmak için bir yardımcı fonksiyon oluşturduk:

Java
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    // ...
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    // ...
  }
});
Node.js
ref.once('value', (data) => {
  // do some stuff once
});
piton
# Import database module.
from firebase_admin import db

# Get a database reference to our posts
ref = db.reference('server/saving-data/fireblog/posts')

# Read the data at the posts reference (this is a blocking operation)
print(ref.get())
Gitmek
// Create a database client from App.
client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// Get a database reference to our posts
ref := client.NewRef("server/saving-data/fireblog/posts")

// Read the data at the posts reference (this is a blocking operation)
var post Post
if err := ref.Get(ctx, &post); err != nil {
	log.Fatalln("Error reading value:", err)
}

Veri Sorgulama

Firebase veritabanı sorgularıyla, çeşitli faktörlere dayalı olarak verileri seçerek alabilirsiniz. Veritabanınızda bir sorgu oluşturmak için, sıralama işlevlerinden birini kullanarak verilerinizin nasıl sıralanmasını istediğinizi belirterek başlayın: orderByChild() , orderByKey() veya orderByValue() . Daha sonra bunları karmaşık sorgular yürütmek için diğer beş yöntemle birleştirebilirsiniz: limitToFirst() , limitToLast() , startAt() , endAt() ve equalTo() .

Firebase'de hepimiz dinozorların oldukça havalı olduğunu düşündüğümüzden, Firebase veritabanınızdaki verileri nasıl sorgulayabileceğinizi göstermek için dinozor gerçeklerinden oluşan örnek bir veritabanından bir pasaj kullanacağız.:

{
  "lambeosaurus": {
    "height" : 2.1,
    "length" : 12.5,
    "weight": 5000
  },
  "stegosaurus": {
    "height" : 4,
    "length" : 9,
    "weight" : 2500
  }
}

Verileri üç şekilde sıralayabilirsiniz: alt anahtara göre, anahtara göre veya değere göre. Temel bir veritabanı sorgusu, her biri aşağıda açıklanan bu sıralama işlevlerinden biriyle başlar.

Belirtilen bir alt anahtara göre sıralama

Bu anahtarı orderByChild() ileterek ortak bir alt anahtarla düğümleri sipariş edebilirsiniz. Örneğin, boylarına göre sıralanmış tüm dinozorları okumak için aşağıdakileri yapabilirsiniz:

Java
public static class Dinosaur {

  public int height;
  public int weight;

  public Dinosaur(int height, int weight) {
    // ...
  }

}

final DatabaseReference dinosaursRef = database.getReference("dinosaurs");
dinosaursRef.orderByChild("height").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    Dinosaur dinosaur = dataSnapshot.getValue(Dinosaur.class);
    System.out.println(dataSnapshot.getKey() + " was " + dinosaur.height + " meters tall.");
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');

ref.orderByChild('height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').get()
for key, val in snapshot.items():
    print('{0} was {1} meters tall'.format(key, val))
Gitmek

// Dinosaur is a json-serializable type.
type Dinosaur struct {
	Height int `json:"height"`
	Width  int `json:"width"`
}

ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("%s was %d meteres tall", r.Key(), d.Height)
}

Sorguladığımız alt anahtara sahip olmayan herhangi bir düğüm, null değeriyle sıralanır, yani sıralamada ilk sırada gelir. Verilerin nasıl sıralandığıyla ilgili ayrıntılar için Veriler Nasıl Sıralanır bölümüne bakın .

Sorgular, yalnızca bir düzey alttaki çocuklar yerine derinlemesine yuvalanmış çocuklar tarafından da sipariş edilebilir. Bu, aşağıdaki gibi derinlemesine iç içe geçmiş verileriniz varsa kullanışlıdır:

{
  "lambeosaurus": {
    "dimensions": {
      "height" : 2.1,
      "length" : 12.5,
      "weight": 5000
    }
  },
  "stegosaurus": {
    "dimensions": {
      "height" : 4,
      "length" : 9,
      "weight" : 2500
    }
  }
}

Yüksekliği şimdi sorgulamak için, tek bir anahtar yerine nesnenin tam yolunu kullanabilirsiniz:

Java
dinosaursRef.orderByChild("dimensions/height").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    // ...
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('dimensions/height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('dimensions/height').get()
for key, val in snapshot.items():
    print('{0} was {1} meters tall'.format(key, val))
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("dimensions/height").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("%s was %d meteres tall", r.Key(), d.Height)
}

Sorgular aynı anda yalnızca bir tuşa göre sipariş verebilir. Aynı sorguda orderByChild() birden çok kez çağrılması hata veriyor.

Anahtara göre sıralama

Ayrıca orderByKey() yöntemini kullanarak düğümleri anahtarlarına göre sıralayabilirsiniz. Aşağıdaki örnek, tüm dinozorları alfabetik sırayla okur:

Java
dinosaursRef.orderByKey().addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
var ref = db.ref('dinosaurs');
ref.orderByKey().on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().get()
print(snapshot)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
snapshot := make([]Dinosaur, len(results))
for i, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	snapshot[i] = d
}
fmt.Println(snapshot)

Değere göre sıralama

orderByValue() yöntemini kullanarak düğümleri alt anahtarlarının değerine göre sıralayabilirsiniz. Diyelim ki dinozorlar bir dino sporları yarışması yapıyor ve siz onların skorlarını aşağıdaki formatta takip ediyorsunuz:

{
  "scores": {
    "bruhathkayosaurus" : 55,
    "lambeosaurus" : 21,
    "linhenykus" : 80,
    "pterodactyl" : 93,
    "stegosaurus" : 5,
    "triceratops" : 22
  }
}

Dinozorları puanlarına göre sıralamak için aşağıdaki sorguyu oluşturabilirsiniz:

Java
DatabaseReference scoresRef = database.getReference("scores");
scoresRef.orderByValue().addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println("The " + dataSnapshot.getKey() + " score is " + dataSnapshot.getValue());
  }

  // ...
});
Node.js
const scoresRef = db.ref('scores');
scoresRef.orderByValue().on('value', (snapshot) => {
  snapshot.forEach((data) => {
    console.log('The ' + data.key + ' dinosaur\'s score is ' + data.val());
  });
});
piton
ref = db.reference('scores')
snapshot = ref.order_by_value().get()
for key, val in snapshot.items():
    print('The {0} dinosaur\'s score is {1}'.format(key, val))
Gitmek
ref := client.NewRef("scores")

results, err := ref.OrderByValue().GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var score int
	if err := r.Unmarshal(&score); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("The %s dinosaur's score is %d\n", r.Key(), score)
}

orderByValue() kullanılırken null , boolean, string ve object değerlerinin nasıl sıralandığına ilişkin bir açıklama için Veriler Nasıl Sıralanır bölümüne bakın.

Karmaşık Sorgular

Artık verilerinizin nasıl sıralandığı açık olduğuna göre, daha karmaşık sorgular oluşturmak için aşağıda açıklanan sınır veya aralık yöntemlerini kullanabilirsiniz.

Sorguları Sınırla

limitToFirst() ve limitToLast() sorguları, belirli bir geri arama için eşitlenecek maksimum çocuk sayısını ayarlamak için kullanılır. 100'lük bir sınır belirlerseniz, başlangıçta yalnızca en fazla 100 child_added olayı alırsınız. Veritabanınızda depolanan 100'den az mesajınız varsa, her mesaj için bir child_added olayı tetiklenir. Ancak, 100'den fazla mesajınız varsa, bu mesajların sadece 100'ü için bir child_added olayı alacaksınız. Bunlar limitToFirst() kullanıyorsanız ilk 100 sıralı mesaj veya limitToFirst() kullanıyorsanız son 100 sıralı limitToLast() . Öğeler değiştikçe, sorguya giren öğeler için child_removed olayları ve onu terk eden öğeler için child_added olayları alırsınız, böylece toplam sayı 100'de kalır.

Dinozor gerçekleri veritabanını ve orderByChild() 'ı kullanarak en ağır iki dinozoru bulabilirsiniz:

Java
dinosaursRef.orderByChild("weight").limitToLast(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('weight').limitToLast(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('weight').limit_to_last(2).get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("weight").LimitToLast(2).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

child_added geri arama, veritabanında depolanan ikiden az dinozor olmadığı sürece tam olarak iki kez tetiklenir. Ayrıca veritabanına eklenen her yeni, daha ağır dinozor için kovulacak. Python'da sorgu, doğrudan en ağır iki dinozoru içeren bir OrderedDict döndürür.

Benzer şekilde, limitToFirst() kullanarak en kısa iki dinozoru bulabilirsiniz:

Java
dinosaursRef.orderByChild("weight").limitToFirst(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').limitToFirst(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').limit_to_first(2).get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").LimitToFirst(2).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

child_added geri arama, veritabanında depolanan ikiden az dinozor olmadığı sürece tam olarak iki kez tetiklenir. Ayrıca, ilk iki dinozordan biri veri tabanından kaldırılırsa, yeni bir dinozor artık ikinci en kısa olacağı için tekrar kovulacak. Python'da sorgu doğrudan en kısa dinozorları içeren bir OrderedDict döndürür.

Ayrıca orderByValue() ile limit sorguları da yapabilirsiniz. En yüksek puan alan 3 dino spor dinozorunun yer aldığı bir lider tablosu oluşturmak istiyorsanız, aşağıdakileri yapabilirsiniz:

Java
scoresRef.orderByValue().limitToFirst(3).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println("The " + dataSnapshot.getKey() + " score is " + dataSnapshot.getValue());
  }

  // ...
});
Node.js
const scoresRef = db.ref('scores');
scoresRef.orderByValue().limitToLast(3).on('value', (snapshot)  =>{
  snapshot.forEach((data) => {
    console.log('The ' + data.key + ' dinosaur\'s score is ' + data.val());
  });
});
piton
scores_ref = db.reference('scores')
snapshot = scores_ref.order_by_value().limit_to_last(3).get()
for key, val in snapshot.items():
    print('The {0} dinosaur\'s score is {1}'.format(key, val))
Gitmek
ref := client.NewRef("scores")

results, err := ref.OrderByValue().LimitToLast(3).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var score int
	if err := r.Unmarshal(&score); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("The %s dinosaur's score is %d\n", r.Key(), score)
}

Aralık Sorguları

startAt() , endAt() ve equalTo() kullanmak, sorgularınız için rastgele başlangıç ​​ve bitiş noktaları seçmenize olanak tanır. Örneğin, en az üç metre boyundaki tüm dinozorları bulmak istiyorsanız, orderByChild() ve startAt() birleştirebilirsiniz:

Java
dinosaursRef.orderByChild("height").startAt(3).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').startAt(3).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').start_at(3).get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").StartAt(3).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

endAt() 'ı sözlükbilimsel olarak isimleri Pterodactyl'den önce gelen tüm dinozorları bulmak için kullanabilirsiniz:

Java
dinosaursRef.orderByKey().endAt("pterodactyl").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByKey().endAt('pterodactyl').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().end_at('pterodactyl').get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().EndAt("pterodactyl").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Sorgunuzun her iki ucunu sınırlamak için startAt() ve endAt() 'ı birleştirebilirsiniz. Aşağıdaki örnek, adı "b" harfiyle başlayan tüm dinozorları bulur:

Java
dinosaursRef.orderByKey().startAt("b").endAt("b\uf8ff").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
var ref = db.ref('dinosaurs');
ref.orderByKey().startAt('b').endAt('b\uf8ff').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().start_at('b').end_at(u'b\uf8ff').get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().StartAt("b").EndAt("b\uf8ff").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

equalTo() yöntemi, tam eşleşmelere göre filtrelemenize olanak tanır. Diğer aralık sorgularında olduğu gibi, eşleşen her alt düğüm için tetiklenir. Örneğin 25 metre boyundaki tüm dinozorları bulmak için aşağıdaki sorguyu kullanabilirsiniz:

Java
dinosaursRef.orderByChild("height").equalTo(25).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').equalTo(25).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
piton
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').equal_to(25).get()
for key in snapshot:
    print(key)
Gitmek
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").EqualTo(25).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Aralık sorguları, verilerinizi sayfalandırmanız gerektiğinde de yararlıdır.

Hepsini bir araya koy

Karmaşık sorgular oluşturmak için tüm bu teknikleri birleştirebilirsiniz. Örneğin, Stegosaurus'tan biraz daha kısa olan dinozorun adını bulabilirsiniz:

Java
dinosaursRef.child("stegosaurus").child("height").addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot stegoHeightSnapshot) {
    Integer favoriteDinoHeight = stegoHeightSnapshot.getValue(Integer.class);
    Query query = dinosaursRef.orderByChild("height").endAt(favoriteDinoHeight).limitToLast(2);
    query.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot dataSnapshot) {
        // Data is ordered by increasing height, so we want the first entry
        DataSnapshot firstChild = dataSnapshot.getChildren().iterator().next();
        System.out.println("The dinosaur just shorter than the stegosaurus is: " + firstChild.getKey());
      }

      @Override
      public void onCancelled(DatabaseError databaseError) {
        // ...
      }
    });
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    // ...
  }
});
Node.js
  const ref = db.ref('dinosaurs');
  ref.child('stegosaurus').child('height').on('value', (stegosaurusHeightSnapshot) => {
    const favoriteDinoHeight = stegosaurusHeightSnapshot.val();

    const queryRef = ref.orderByChild('height').endAt(favoriteDinoHeight).limitToLast(2);
    queryRef.on('value', (querySnapshot) => {
      if (querySnapshot.numChildren() === 2) {
        // Data is ordered by increasing height, so we want the first entry
        querySnapshot.forEach((dinoSnapshot) => {
          console.log('The dinosaur just shorter than the stegasaurus is ' + dinoSnapshot.key);

          // Returning true means that we will only loop through the forEach() one time
          return true;
        });
      } else {
        console.log('The stegosaurus is the shortest dino');
      }
    });
});
piton
ref = db.reference('dinosaurs')
favotire_dino_height = ref.child('stegosaurus').child('height').get()
query = ref.order_by_child('height').end_at(favotire_dino_height).limit_to_last(2)
snapshot = query.get()
if len(snapshot) == 2:
    # Data is ordered by increasing height, so we want the first entry.
    # Second entry is stegosarus.
    for key in snapshot:
        print('The dinosaur just shorter than the stegosaurus is {0}'.format(key))
        return
else:
    print('The stegosaurus is the shortest dino')
Gitmek
ref := client.NewRef("dinosaurs")

var favDinoHeight int
if err := ref.Child("stegosaurus").Child("height").Get(ctx, &favDinoHeight); err != nil {
	log.Fatalln("Error querying database:", err)
}

query := ref.OrderByChild("height").EndAt(favDinoHeight).LimitToLast(2)
results, err := query.GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
if len(results) == 2 {
	// Data is ordered by increasing height, so we want the first entry.
	// Second entry is stegosarus.
	fmt.Printf("The dinosaur just shorter than the stegosaurus is %s\n", results[0].Key())
} else {
	fmt.Println("The stegosaurus is the shortest dino")
}

Veriler Nasıl Sıralanır?

Bu bölüm, dört sıralama işlevinin her birini kullanırken verilerinizin nasıl sıralandığını açıklar.

siparişByChild

orderByChild() kullanılırken, belirtilen alt anahtarı içeren veriler aşağıdaki gibi sıralanır:

  1. Belirtilen alt anahtar için null değeri olan çocuklar önce gelir.
  2. Ardından, belirtilen alt anahtar için false değerine sahip çocuklar gelir. Birden çok alt öğe false değerine sahipse, bunlar anahtara göre sözlükbilimsel olarak sıralanır.
  3. Ardından belirtilen alt anahtar için true değerine sahip çocuklar gelir. Birden çok alt öğe true değerine sahipse, bunlar anahtara göre sözlükbilimsel olarak sıralanır.
  4. Sayısal değeri olan çocuklar, artan düzende sıralanır. Birden çok alt öğe, belirtilen alt düğüm için aynı sayısal değere sahipse, bunlar anahtara göre sıralanır.
  5. Dizeler sayılardan sonra gelir ve sözlükbilimsel olarak artan düzende sıralanır. Birden çok alt öğe, belirtilen alt düğüm için aynı değere sahipse, anahtara göre sözlükbilimsel olarak sıralanır.
  6. Nesneler en son gelir ve anahtara göre artan düzende sözlükbilimsel olarak sıralanır.

siparişByKey

Verilerinizi sıralamak için orderByKey() kullanırken, veriler aşağıdaki gibi anahtara göre artan sırada döndürülür. Anahtarların yalnızca dize olabileceğini unutmayın.

  1. 32-bit tamsayı olarak ayrıştırılabilen bir anahtarı olan çocuklar, artan düzende sıralanarak önce gelir.
  2. Anahtar olarak dize değerine sahip çocuklar, sözlükbilimsel olarak artan düzende sıralanır.

siparişByValue

orderByValue() kullanılırken, çocuklar değerlerine göre sıralanır. Sıralama ölçütü, belirtilen bir alt anahtarın değeri yerine düğümün değerinin kullanılması dışında orderByChild() ile aynıdır.