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. Admin SDK'da veri alımı, farklı programlama dillerinde biraz farklı şekilde uygulanır.

  1. Eşzamansız dinleyiciler: Firebase Gerçek Zamanlı Veritabanında depolanan veriler, bir veritabanı referansına eşzamansız bir dinleyici eklenerek alınır. Dinleyici, verinin başlangıç ​​durumu için bir kez ve veri değiştiğinde tekrar tetiklenir. Bir olay dinleyicisi birkaç farklı türde olay alabilir. Bu veri alma modu Java, Node.js ve Python Admin SDK'larında desteklenir.
  2. Okumaları engelleme: 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ı tek seferlik bir işlemdir. Bu, SDK'nın sonraki veri güncellemelerini dinleyen herhangi bir geri aramayı kaydetmediği anlamına gelir. Bu veri alma modeli Python ve Go Admin SDK'larında desteklenir.

Başlarken

Firebase veritabanındaki verilerin nasıl okunacağını anlamak için önceki makaledeki blog yazma örneğini tekrar ele alalım. Örnek uygulamadaki blog gönderilerinin https://docs-examples.firebaseio.com/server/tained-data/fireblog/posts.json veritabanı URL'sinde saklandığı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);
}); 
Python
# 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, konsolda kayıtlı tüm gönderilerinizi içeren bir nesne göreceksiniz. Node.js ve Java durumunda, veritabanı referansınıza yeni veriler eklendiğinde dinleyici işlevi çağrılır ve bunun gerçekleşmesi için herhangi bir ekstra kod yazmanıza gerek yoktur.

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

Yukarıdaki örnekte, yalnızca tek bir veri parçası değişse bile 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'deki Etkinlik Türlerini Okuyun

Değer

value olayı, okuma olayı sırasında mevcut olan belirli bir veritabanı yolundaki içeriklerin statik 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 çağrısına, alt veriler de dahil olmak üzere o konumdaki tüm verileri içeren bir anlık görüntü 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 çağırma işlevi tüm yazıları döndürecektir.

Ç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 ve daha sonra belirtilen yola yeni bir alt öğe eklendiğinde tekrar tetiklenir. Olay geri çağrısına, yeni alt öğenin verilerini içeren bir anlık görüntü 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ü, ayrı bir blog gönderisine sahip bir nesneyi 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 argümanından önceki gönderi kimliğine de erişebilirsiniz.

Çocuk Değiştirildi

child_changed olayı, bir alt düğüm değiştirildiğinde her zaman tetiklenir. Bu, alt düğümün alt öğelerinde yapılan değişiklikleri de 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 iletilen anlık görüntü, alt öğe için güncellenmiş verileri içerir.

Blog gönderilerindeki güncellenmiş verileri düzenlendiklerinde 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ı, hemen bir alt öğe kaldırıldığında tetiklenir. Genellikle child_added ve child_changed ile birlikte kullanılır. Olay geri çağrısına iletilen anlık görüntü, kaldırılan alt öğeye ilişkin verileri içerir.

Blog örneğinde, silinen gönderiyle ilgili konsola 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ı, bir sonraki bölümde ele alınan sıralı verilerle çalışırken kullanılır.

Etkinlik Garantileri

Firebase veritabanı etkinliklerle ilgili birkaç önemli garanti vermektedir:

Veritabanı Olay Garantileri
Yerel durum değiştiğinde olaylar her zaman tetiklenecektir.
Ağ bağlantısının geçici olarak kesilmesi gibi yerel operasyonların veya zamanlamanın geçici farklılıklara neden olduğu durumlarda bile, olaylar her zaman sonuçta verilerin doğru durumunu yansıtacaktır.
Tek bir istemciden yapılan yazma işlemleri her zaman sunucuya yazılacak ve diğer kullanıcılara sırayla yayınlanacaktır.
Değer olayları her zaman en son tetiklenir ve anlık görüntünün alınmasından önce meydana gelen diğer olaylara ait güncellemeleri içermesi garanti edilir.

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

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, 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);

Bir kapsam bağlamını on() işlevine aktardıysanız, geri çağrıyı ayırırken bunun iletilmesi gerekir:

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

Bir konumdaki tüm geri aramaları kaldırmak istiyorsanız 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 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
});
Python
# 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)
}

Verileri 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 karmaşık sorgular yürütmek için bunları 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 dinozorlarla ilgili gerçekleri içeren ö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

Düğümleri ortak bir alt anahtara göre, bu anahtarı orderByChild() işlevine ileterek sıralayabilirsiniz. Örneğin tüm dinozorları boylarına göre sıralayarak 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');
});
Python
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; bu, sıralamada ilk sırada yer alacağı anlamına gelir. Verilerin nasıl sıralandığına ilişkin ayrıntılar için Veriler Nasıl Sıralanır bölümüne bakın.

Sorgular, yalnızca bir düzey aşağıdaki çocuklar yerine derin yuvalanmış çocuklar tarafından da sıralanabilir. Bunun gibi derinlemesine iç içe geçmiş verileriniz varsa bu kullanışlıdır:

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

Artık yüksekliği 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');
});
Python
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 anahtara göre sıralanabilir. Aynı sorguda orderByChild() işlevinin birden çok kez çağrılması hataya neden olur.

Anahtara göre sipariş verme

orderByKey() yöntemini kullanarak düğümleri anahtarlarına göre de sıralayabilirsiniz. Aşağıdaki örnekte tüm dinozorlar alfabetik sırayla okunur:

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);
});
Python
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 spor yarışması düzenliyor ve siz de 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());
  });
});
Python
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 nesne değerlerinin nasıl sıralandığı hakkında bir açıklama için Verilerin Sıralanması bölümüne bakın.

Karmaşık Sorgular

Artık verilerinizin nasıl sıralandığı netleştiğine göre, daha karmaşık sorgular oluşturmak için aşağıda açıklanan limit veya aralık yöntemlerini kullanabilirsiniz.

Sorguları Sınırla

limitToFirst() ve limitToLast() sorguları, belirli bir geri arama için senkronize edilecek maksimum alt çocuk sayısını ayarlamak için kullanılır. 100'lük bir sınır ayarlarsanız başlangıçta yalnızca 100'e kadar child_added olayı alırsınız. Veritabanınızda 100'den az mesaj depolanıyorsa her mesaj için bir child_added olayı tetiklenir. Ancak 100'den fazla mesajınız varsa, bu mesajların yalnızca 100'ü için child_added etkinliği alırsınız. Bunlar, limitToFirst() kullanıyorsanız ilk 100 sıralı mesajdır veya limitToLast() kullanıyorsanız son 100 sıralı mesajdır. Öğeler değiştikçe, sorguya giren öğeler için child_added olaylarını ve sorgudan ayrılan öğeler için child_removed olaylarını alırsınız; böylece toplam sayı 100'de kalır.

Dinozor gerçekleri veritabanını ve orderByChild() yöntemini 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);
});
Python
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 çağırma, veritabanında ikiden az dinozor depolanmadığı sürece tam olarak iki kez tetiklenir. Ayrıca veritabanına eklenen her yeni, daha ağır dinozor için de kovulacak. Python'da sorgu doğrudan en ağır iki dinozoru içeren OrderedDict döndürür.

Benzer şekilde, limitToFirst() işlevini 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);
});
Python
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 çağırma, veritabanında ikiden az dinozor depolanmadığı sürece tam olarak iki kez tetiklenir. Ayrıca ilk iki dinozordan biri veri tabanından kaldırılırsa tekrar ateşlenecek, çünkü yeni dinozor artık en kısa ikinci dinozor olacak. Python'da sorgu doğrudan en kısa dinozorları içeren OrderedDict döndürür.

Ayrıca orderByValue() ile limit sorguları da gerçekleştirebilirsiniz. En yüksek puanı alan dino sporu dinozorlarının ilk 3'ünü içeren bir liderlik 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());
  });
});
Python
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() öğelerini 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);
});
Python
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())
}

Sözlüksel olarak adları Pterodactyl'den önce gelen tüm dinozorları bulmak için endAt() 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);
});
Python
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 da 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);
});
Python
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 filtreleme yapmanıza olanak tanır. Diğer aralık sorgularında olduğu gibi eşleşen her alt düğüm için tetiklenecektir. Örneğin boyu 25 metre olan 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);
});
Python
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 kullanışlıdır.

Hepsini bir araya koy

Karmaşık sorgular oluşturmak için bu tekniklerin tümünü 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');
      }
    });
});
Python
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ümde, dört sıralama fonksiyonunun her birini kullanırken verilerinizin nasıl sıralandığı açıklanmaktadır.

siparişByChild

orderByChild() kullanıldığında, belirtilen alt anahtarı içeren veriler şu şekilde sıralanır:

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

siparişByKey

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

  1. 32 bitlik bir tamsayı olarak ayrıştırılabilen anahtarı olan çocuklar, artan düzende sıralanarak önce gelir.
  2. Anahtarları dize değeri olan çocuklar daha sonra sözlükbilimsel olarak artan düzende sıralanır.

siparişByValue

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