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 alma, farklı programlama dillerinde biraz farklı şekilde uygulanır.
- Eşzamansız dinleyiciler: Bir Firebase Gerçek Zamanlı Veritabanında depolanan veriler, bir veritabanı referansına eşzamansız bir dinleyici eklenerek alınır. Dinleyici, verilerin ilk durumu için bir kez ve veriler 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.
- Engelleme okumaları: 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ı, tek seferlik bir işlemdir. Bu, SDK'nın sonraki veri güncellemelerini dinleyen geri aramaları 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 oluşturma ö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 kaydettiğiniz tüm gönderilerinizi içeren bir nesne görürsünüz. Node.js ve Java söz konusu olduğunda, veritabanı referansınıza yeni veriler eklendiğinde dinleyici işlevi çağrılır ve bunun gerçekleşmesi için fazladan kod yazmanıza gerek yoktur.
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ü, belirli bir veritabanı referansındaki verilerin tek bir zamanda 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, doğrudan verilerin bir Python temsilini döndürür. Go'daki Get()
işlevi, verileri belirli bir veri yapısına ayırır.
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ı, belirli bir veritabanı yolundaki içeriğin statik bir anlık görüntüsünü, read olayı sırasında var oldukları şekliyle 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ü iletilir. Yukarıdaki kod örneğinde value
, uygulamanızdaki tüm blog gönderilerini döndürdü. Her yeni blog gönderisi eklendiğinde, geri arama işlevi tüm gönderileri 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
aksine, child_added
mevcut her alt öğe için bir kez ve ardından belirtilen yola her yeni çocuk eklendiğinde tekrar tetiklenir. Olay geri araması, yeni çocuğun 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 nesne içerecektir. SDK, değeri alarak gönderileri nesnelere dönüştürdüğünden, sırasıyla author
ve title
çağırarak gönderinin yazar ve başlık özelliklerine erişebilirsiniz. İkinci 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 değiştirildiğinde her zaman tetiklenir. Bu, alt düğümün alt öğelerinde yapılan tüm değişiklikleri içerir. Bir öğe listesindeki değişikliklere yanıt vermek için genellikle child_added
ve child_removed
ile birlikte kullanılır. Olay geri aramasına iletilen anlık görüntü, alt öğe için güncellenmiş verileri içerir.
child_changed
düzenlendikleri zaman blog gönderilerindeki güncellenmiş verileri okumak için 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 aramasına iletilen anlık görüntü, kaldırılan alt öğenin verilerini içerir.
Blog örneğinde, silinen gönderiyle ilgili bir bildirimi konsola 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ı, olaylarla ilgili birkaç önemli garanti verir:
Veritabanı Olay Garantileri |
---|
Yerel durum değiştiğinde olaylar her zaman tetiklenecektir. |
Yerel işlemlerin veya zamanlamanın ağ bağlantısının geçici olarak kesilmesi 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 yazma işlemleri her zaman sunucuya yazılır ve sırayla diğer kullanıcılara yayınlanır. |
Value olayları her zaman en son tetiklenir ve bu anlık görüntü alınmadan önce meydana gelen diğer olaylardan güncellemeleri içermesi garanti edilir. |
Value olayları her zaman en son tetiklendiğinden, aşağıdaki örnek her zaman çalışı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ırma
Geri aramalar, aşağıdaki gibi kaldırılacak olay türü ve geri çağırma 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 aramayı ayırırken iletilmesi gerekir:
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ı işlev 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 karmaşık sorgular yürütmek için bunları diğer beş yöntemle birleştirebilirsiniz: limitToFirst()
, limitToLast()
, startAt()
, endAt()
ve equalTo()
.
Firebase'deki 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.
Belirli bir alt anahtara göre sıralama
Düğümleri, bu anahtarı orderByChild()
işlevine geçirerek ortak bir alt anahtara göre sıralayabilirsiniz. Ö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 gelir. Verilerin nasıl sıralandığıyla ilgili ayrıntılar için Verilerin Nasıl Sıralandığı bölümüne bakın.
Sorgular, yalnızca bir düzey alttaki çocuklar yerine, derinlemesine iç içe geçmiş çocuklar tarafından da sıralanabilir. 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 anahtara göre sipariş verebilir. Aynı sorguda orderByChild()
birden çok kez çağırmak hata verir.
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 dino sporları yarışması yapıyorlar ve siz onların puanları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ığı netleştiğine 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 senkronize edilecek maksimum çocuk sayısını ayarlamak için kullanılır. 100'lük bir sınır belirlerseniz, başlangıçta yalnızca 100'e kadar 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 yalnızca 100'ü için bir child_added
olayı alırsınız. Bunlar, limitToFirst()
kullanıyorsanız sıralanan ilk 100 mesaj veya limitToLast()
kullanıyorsanız sıralanan son 100 mesajdır. Öğeler değiştikçe, sorguya giren öğeler için child_added
olayları ve sorgudan ayrılan öğeler için child_removed
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 araması, 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, en kısa iki dinozoru limitToFirst()
kullanarak 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 araması, 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 tekrar ateşlenir, çü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 sorgulamaları da yapabilirsiniz. En yüksek puanı alan ilk 3 dino sporu dinozorunu 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()); }); });
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 rasgele 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()) }
Sözlüksel olarak adları Pterodactyl'den önce gelen tüm dinozorları bulmak için endAt()
işlevini 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 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); });
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 filtreleme yapmanızı sağlar. 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 kullanışlı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 şu şekilde sıralanır:
- Belirtilen alt anahtar için
null
değere sahip çocuklar önce gelir. - Ardından, belirtilen alt anahtar için
false
değerine sahip alt öğeler gelir. Birden fazla alt öğefalse
değerine sahipse, bunlar sözlüksel olarak anahtara göre sıralanır. - Ardından, belirtilen alt anahtar için
true
değerine sahip alt öğeler gelir. Birden fazla alt öğetrue
değerine sahipse, bunlar sözlüksel olarak anahtara göre sıralanır. - 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.
- Dizeler sayılardan sonra gelir ve sözlüksel 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üksel olarak sıralanır.
- Nesneler en son gelir ve artan düzende anahtara göre sözlüksel olarak 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 dize olabileceğini unutmayın.
- 32 bitlik bir tamsayı olarak ayrıştırılabilen bir anahtarı olan alt öğeler, artan düzende sıralanarak önce gelir.
- Sırada anahtarları dize değeri olan çocuklar gelir ve sözlüksel 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 alt anahtarın değeri yerine düğümün değerinin kullanılması dışında orderByChild()
ile aynıdır.