Veri Alma

Bu dokümanda, veritabanı verilerini almayla ilgili temel bilgiler, verilerin nasıl sıralandığı ve verilerin nasıl sıralandığı açıklanmaktadır. basit sorgulara dönüştü. Yönetici SDK'sinde veri alma, farklı uygulamalarda biraz farklı uygulanır. programlama dilleri arasında.

  1. Eşzamansız dinleyiciler: Firebase Realtime Database içinde depolanan veriler, kullanır. İşleyici, verilerin ilk durumu için bir kez tetiklenir ve işlemi tekrarlamanız gerekir. Bir etkinlik dinleyicisi birkaç farklı etkinlik türleri hakkında daha fazla bilgi edinin. Bu veri alma modu desteklenir .
  2. Okumaları engelleme: Firebase Realtime Database içinde depolanan veriler, veritabanında engelleme yöntemi çağırarak alınır referansta depolanan verileri döndürür. Her yöntem çağrısı, işlemidir. Bu, SDK'nın sonraki veri güncellemelerini dinleyen geri çağırmaları kaydetmediği anlamına gelir. Bu veri alma modeli, Python ve Go Yönetici SDK'larında desteklenir.

Başlarken

Firebase veritabanındaki verilerin nasıl okunacağını anlamak için önceki makalede verilen blog örneğini tekrar gözden geçirelim. Geri Çağırma örnek uygulamadaki blog yayınlarının veritabanı URL'sinde saklandığına https://docs-examples.firebaseio.com/server/saving-data/fireblog/post.json. Yayın 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())
Go
// Post is a json-serializable type.
type Post struct {
	Author string `json:a"uthor,omitempty`"
	Title  string `json:t"itle,omitempty`"
}

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

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

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

Yukarıdaki kodu çalıştırırsanız konsola kaydedilen tüm yayınlarınızı içeren bir nesne görürsünüz. Node.js ve Java'da işleyici işlevi, veritabanı referansınıza her yeni veri eklendiğinde çağrılır ve bunun için fazladan kod yazmanız gerekmez.

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 zamandaki tek bir veritabanı referansındaki verilerin bir resmidir. Anlık görüntüde val() / getValue() çağrılması, verilerin dile özgü nesne gösterimini döndürür. Referansın konumunda herhangi bir veri yoksa anlık görüntünün değeri null olur. Python'daki get() yöntemi, doğrudan verilerin Python gösterimini döndürür. Go'daki Get() işlevi, verileri belirli bir veri yapısına ayırır.

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

Java ve Node.js'de Etkinlik Türlerini Okuma

Değer

value etkinliği, okuma etkinliği sırasında mevcut oldukları için belirli bir veritabanı yolundaki içeriğin statik anlık görüntüsünü okumak için kullanılır. İlk verilerde bir kez, veriler her değiştiğinde tekrar tetiklenir. Etkinlik geri çağırmasına, alt veriler de dahil olmak üzere söz konusu konumdaki tüm verileri içeren bir anlık görüntü iletilir. Yukarıdaki kod örneğinde value, uygulamanızdaki tüm blog yayınlarını döndürdü. Yeni bir blog yayını her eklendiğinde, geri çağırma işlevi tüm yayınları döndürür.

Alt Öğe Eklendi

child_added etkinliği genellikle veritabanından bir öğe listesi alınırken kullanılır. Konumun tüm içeriğini döndüren value işlevinin aksine child_added, mevcut her alt öğe için bir kez ve belirtilen yola her yeni alt öğe eklendiğinde tekrar tetiklenir. Etkinlik geri çağırmasına, yeni alt öğenin verilerini içeren bir anlık görüntü iletilir. Sıralama amacıyla, önceki alt öğenin anahtarını içeren ikinci bir bağımsız değişken de iletilir.

Yalnızca blog uygulamanıza eklenen her yeni yayınla ilgili verileri almak istiyorsanız child_added özelliğini 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 örnekteki anlık görüntü, tek bir blog yayını olan bir nesne içerir. SDK, değeri alarak yayınları nesnelere dönüştürdüğünden, sırasıyla author ve title yöntemini çağırarak yayının yazar ve başlık özelliklerine erişebilirsiniz. Ayrıca, ikinci prevChildKey bağımsız değişkeninden önceki yayın kimliğine erişebilirsiniz.

Alt Öğe Değişti

Bir alt düğüm her değiştirildiğinde child_changed etkinliği tetiklenir. Buna, herhangi bir alt düğümün alt öğelerinde yapılan değişikliklerdir. Genellikle child_added ile birlikte kullanılır ve bir öğe listesinde yapılan değişikliklere yanıt vermek için child_removed tuşlarına basın. Etkinlik geri çağırmasına iletilen anlık görüntü, alt öğeye ait güncellenmiş verileri içerir.

Düzenlenen blog yayınlarındaki güncellenmiş verileri okumak için child_changed uygulamasını 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ı

Hemen bir alt öğe kaldırıldığında child_removed etkinliği tetiklenir. Genellikle child_added ve child_changed ile birlikte kullanılır. Etkinlik geri çağırmasına iletilen anlık görüntü, kaldırılan alt öğenin verilerini içerir.

Blog örneğinde, silinen yayınla ilgili bildirimi konsola kaydetmek için child_removed öğesini 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 etkinliği, sıralı verilerle çalışırken kullanılır. Bu konu sonraki bölümde açıklanmıştır.

Etkinlik Garantileri

Firebase veritabanı, etkinliklerle ilgili bazı önemli garantiler verir:

Veritabanı Etkinliği Garantileri
Etkinlikler her zaman yerel durum değiştiğinde tetiklenir.
Etkinlikler, yerel operasyonların veya faaliyetlerin söz konusu olduğu durumlarda bile, her zaman verilerin doğru durumunu yansıtır. zamanlama, ağ bağlantısının geçici olarak kesilmesi gibi geçici farklılıklara neden olur.
Tek bir istemciden yapılan yazmalar her zaman sunucuya yazılır ve sırayla diğer kullanıcılara yayınlanır.
Değer etkinlikleri her zaman en son tetiklenir ve gerçekleşen diğer tüm etkinliklerin güncellemeleri içermesi garanti edilir yeni bir ekran görüntüsü alıyor.

Değer etkinlikleri 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 Çağırmaları Çıkarma

Geri çağırma işlevleri, kaldırılacak etkinlik türünün ve geri çağırma işlevinin belirtilmesiyle kaldırılır. Örneğin:

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şlevine bir kapsam bağlamı ilettiyseniz geri çağırma yapılırken bu bağlam iletilmelidir:

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

Bir konumdaki tüm geri çağırmaları 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 Okuma

Bazı durumlarda, bir geri çağırmanın bir kez çağrıldıktan sonra hemen kaldırılması yararlı olabilir. Bir yardımcı oluşturduk işlevini kullanın:

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())
Go
// 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 göre seçerek verileri alabilirsiniz. Veritabanınızda bir sorgu oluşturmak için öncelikle verilerinizin nasıl sıralanmasını istediğinizi şu sıralama işlevlerinden birini kullanarak belirtirsiniz: orderByChild(), orderByKey() veya orderByValue(). Daha sonra karmaşık sorgular gerçekleştirmek için bunları beş diğer yöntemle birleştirebilirsiniz: limitToFirst(), limitToLast(), startAt(), endAt() ve equalTo().

Firebase'de hepimiz dinozorların oldukça havalı olduğunu düşünüyorduk. Bu nedenle, Firebase veritabanınızdaki verileri nasıl sorgulayabileceğinizi göstermek için dinozorlarla ilgili bilgi içeren örnek bir veritabanından bir snippet kullanacağız.

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

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

Belirtilen alt anahtara göre sıralama

Düğümleri, ortak bir alt anahtara göre sıralayarak bu anahtarı orderByChild() hizmetine iletebilirsiniz. Örneğin, boylarına göre sıralanmış tüm dinozorları okumak için şunları yapabilirsiniz: şu:

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))
Go
// Dinosaur is a json-serializable type.
type Dinosaur struct {
	Height int `json:h"eight`"
	Width  int `json:w"idth`"
}

ref := client.NewRef(d"inosaurs)"

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

Sorguladığımız alt anahtara sahip olmayan tüm düğümler, null değeriyle sıralanır. Yani sıralamada bu anahtar ilk sırada yer alır. 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 seviye altındaki alt öğeler yerine derinlemesine iç içe yerleştirilmiş alt öğelere göre de sıralanabilir. Bu yöntem, aşağıdakiler gibi derinlemesine iç içe yerleştirilmiş verileriniz varsa yararlı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');
});
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))
Go
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. orderByChild() aranıyor aynı sorgu için birden çok kez hata verdiğinde.

Anahtara göre sıralama

Düğümleri, orderByKey() yöntemini kullanarak anahtarlarına göre de sıralayabilirsiniz. İlgili içeriği oluşturmak için kullanılan aşağıdaki örnekte tüm dinozorlar alfabetik sırayla yazılmaktadır:

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)
Go
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. Dinozorların dinozor sporları müsabakasına katıldığını ve skorlarını aşağıdaki biçimde takip ettiğinizi varsayalım:

{
  "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))
Go
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, boole, dize ve nesne değerlerinin nasıl sıralandığına ilişkin bir açıklama için Veriler Nasıl Düzenlenir? bölümüne bakın.

Karmaşık Sorgular

Verilerinizin nasıl sıralandığı artık açık olduğuna 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 çağırma için senkronize edilecek maksimum alt öğe sayısı. 100'lük bir sınır belirlerseniz başlangıçta en fazla 100 child_added etkinliği alır. Örneğin, 100 ileti saklanırsa her biri için bir child_added etkinliği tetiklenir mesajını alırsınız. Ancak 100'den fazla iletiniz varsa yalnızca bir child_added alırsınız. tek bir etkinliği kapsar. Bu mesaj ilk 100 sıradaki mesajdır: limitToFirst() veya sipariş edilen son 100 mesaj limitToLast(). Öğeler değiştikçe child_added etkinlik alacaksınız ve bu sorgudan ayrılan öğeler için child_removed etkinlikleri Böylece toplam sayı 100'de kalır.

Dinozorlarla ilgili bilgiler veritabanını ve orderByChild() özelliğini kullanarak en ağır olan iki yanıtı bulabilirsiniz dinozorlar:

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)
Go
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ğırması tam olarak iki kez tetiklenir. ikiden az dinozor bulunduğunu tespit ettik. Ayrıca, veritabanına eklenen her yeni ve daha ağır dinozor için de püskürtülür. 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);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').limit_to_first(2).get()
for key in snapshot:
    print(key)
Go
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())
}

Veritabanında depolanan ikiden az dinozor olmadığı sürece, child_added geri çağırması tam olarak iki kez tetiklenir. Ayrıca ilk iki dinozordan biri veritabanından kaldırılırsa da tekrar etkinleşir. Çünkü yeni bir dinozor, artık en kısa ikinci dinozor olacaktır. Python'da, sorgu doğrudan en kısa dinozorları içeren bir OrderedDict döndürür.

Ayrıca orderByValue() ile sınır sorgusu gerçekleştirebilirsiniz. Dinozorlar arasında en yüksek puanı alan 3 dinozoru içeren bir skor 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))
Go
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() özelliklerini kullanarak şunları yapabilirsiniz: sorgularınız için rastgele başlangıç ve bitiş noktaları seçebilirsiniz. Örneğin, Yeşil Ofis projenizde uzunluğu en az üç metre olan tüm dinozorları bulmak için orderByChild() ve startAt():

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)
Go
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())
}

Adları Pterodaktil'den önce gelen tüm dinozorları bulmak için endAt() yönergesini kullanabilirsiniz. sözlüksel olarak:

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)
Go
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())
}

Hedefinizin her iki ucunu da sınırlamak için startAt() ve endAt() özelliklerini birlikte kullanabilirsiniz. emin olun. Aşağıdaki örnekte, adları "b" ile başlayan tüm dinozorlar bulunmuştur:

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)
Go
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şlemelere göre filtreleme yapmanıza olanak tanır. Her zaman olduğu gibi diğer aralık sorgularıyla eşleşirse, eşleşen her alt düğüm için etkinleşir. Örneğin, şunları yapabilirsiniz: 25 metre uzunluğundaki tüm dinozorları bulmak için aşağıdaki sorguyu kullanın:

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)
Go
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 sayfalara ayırmanız gerektiğinde de yararlı olur.

Tüm unsurların birleşimi

Karmaşık sorgular oluşturmak için bu tekniklerin tümünü birleştirebilirsiniz. Örneğin, her hafta dinozorun adı, Stegosaurus'tan biraz daha kısadır:

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')
Go
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 işlevinin her biri kullanılırken verilerinizin nasıl sıralandığı açıklanmaktadır.

sıralamaYazarı

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

  1. Belirtilen alt anahtarda null değerine sahip olan alt öğeler önce gelir.
  2. Belirtilen alt anahtar için false değerine sahip olan alt öğeler ardından gelir. Birden fazla alt öğe false değerine sahipse bunlar anahtara göre sözlüksel olarak sıralanır.
  3. Belirtilen alt anahtar için true değerine sahip olan alt öğeler ardından gelir. Birden fazla alt öğe true değerine sahipse bunlar sözlüksel olarak anahtara göre sıralanır.
  4. Sayısal değere sahip olan alt öğeler artan düzende sıralanır. Birden fazla alt düğüm, 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üksel olarak artan düzende sıralanır. Birden fazla alt düğüm, 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 yer alır ve sözlüklere göre anahtara göre artan düzende sıralanır.

anahtara göre sipariş

Verilerinizi sıralamak için orderByKey() kullandığınızda 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 tam sayı olarak ayrıştırılabilen bir anahtarı olan alt öğeler önce gelir ve artan düzende sıralanır.
  2. Anahtarlarında dize değeri olan alt öğeler sıradaki sırayla, sözlüksel olarak artan düzende sıralanır.

siparişe Göre Değer

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