Bu belgede veritabanı verilerini alma, verilerin nasıl sıralandığı ve veriler üzerinde basit sorguların nasıl yapılacağı ele alınmaktadır. Admin SDK'daki veri alma işlemi, farklı programlama dillerinde biraz daha farklı şekilde uygulanır.
- Eşzamansız dinleyiciler: Firebase Realtime Database'de depolanan veriler, veritabanı referansına eşzamansız bir işleyici eklenerek alınır. İşleyici, verilerin ilk durumu için bir kez ve veriler her değiştiğinde tekrar tetiklenir. Bir etkinlik işleyici birkaç farklı etkinlik türü alabilir. Bu veri alma modu Java, Node.js ve Python Admin SDK'larında desteklenir.
- Engelleme okumaları: Firebase Realtime Database'de depolanan veriler, bir veritabanı referansında engelleme yöntemi çağırılarak alınır ve bu yöntem, referansta depolanan verileri döndürür. Her yöntem çağrısı tek seferlik bir işlemdir. Yani SDK, sonraki veri güncellemelerini dinleyen geri çağırmaları kaydetmez. Bu veri alma modeli Python ve Go Admin SDK'larında desteklenir.
Başlayın
Firebase veritabanından verilerin nasıl okunacağını anlamak için önceki makalede verilen blog örneğine tekrar bakalım. Örnek uygulamadaki blog yayınlarının https://docs-examples.firebaseio.com/server/saving-data/fireblog/posts.json veritabanı URL'sinde depolandığını hatırlayın. 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:"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 günlüğe kaydedilen tüm yayınlarınızı içeren bir nesne görürsünüz. Node.js ve Java söz konusu olduğunda, veritabanı referansınıza yeni veri eklendiğinde dinleyici işlevi çağrılır. Bunun için ekstra 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 veritabanı referansında, tek bir noktada bulunan verilerin resmidir. Bir anlık görüntüde val()
/ getValue()
çağrısı, verilerin dile özgü nesne temsilini döndürür. Referansın konumunda hiç veri yoksa anlık görüntünün değeri null
olur. Python'daki get()
yöntemi, verilerin doğrudan bir Python gösterimini döndürür. Go'daki Get()
işlevi, verileri belirli bir veri yapısı halinde somutlaştırır.
Yukarıdaki örnekte, yalnızca bir veri parçası değiştirilmiş 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, belirli bir veritabanı yolundaki içeriklerin okuma etkinliği sırasında var olan statik anlık görüntüsünü okumak için kullanılır. İlk verilerle birlikte bir kez ve veriler her değiştiğinde tekrar tetiklenir. Etkinlik geri çağırma özelliğine, 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ü. Her yeni blog yayını 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 öğ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ı, yeni alt öğenin verilerini içeren bir anlık görüntü iletir. Sıralama amacıyla, buna, ö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ına ilişkin verileri almak istiyorsanız child_added
öğesini 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 yayını içeren bir nesne içerecektir. SDK, değeri alarak yayınları nesnelere dönüştürdüğünden, sırasıyla author
ve title
çağrılarını yaparak yayının yazar ve başlık özelliklerine erişebilirsiniz. İkinci prevChildKey
bağımsız değişkeninden önceki yayın kimliğine de erişebilirsiniz.
Çocuk Değişti
child_changed
etkinliği, bir alt düğüm her değiştirildiğinde tetiklenir. Buna, alt düğümün alt öğeleri üzerinde yapılan tüm değişiklikler dahildir. Bir öğe listesinde yapılan değişikliklere yanıt vermek için genellikle child_added
ve child_removed
ile birlikte kullanılır. Etkinlik geri çağırmaya iletilen anlık görüntü, alt öğe için güncellenmiş verileri içerir.
Düzenlenen blog yayınlarındaki güncellenmiş verileri okumak için child_changed
kullanabilirsiniz:
Java
ref.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {} @Override public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) { Post changedPost = dataSnapshot.getValue(Post.class); System.out.println("The updated post title is: " + changedPost.title); } @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {} @Override public void onCancelled(DatabaseError databaseError) {} });
Node.js
// Get the data on a post that has changed ref.on('child_changed', (snapshot) => { const changedPost = snapshot.val(); console.log('The updated post title is ' + changedPost.title); });
Çocuk Kaldırıldı
Birinci sınıf çocuk kaldırıldığında child_removed
etkinliği tetiklenir. Genellikle child_added
ve child_changed
ile birlikte kullanılır. Etkinlik geri çağırmaya iletilen anlık görüntü, kaldırılan alt öğenin verilerini içerir.
Blog örneğinde, silinmiş yayınla ilgili konsolda bir bildirimi günlüğe kaydetmek için child_removed
aracını 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 ele alınmıştır.
Etkinlik Garantileri
Firebase veritabanı, etkinliklerle ilgili bazı önemli garantiler verir:
Veritabanı Etkinliği Garantileri |
---|
Yerel durum değiştiğinde etkinlikler her zaman tetiklenir. |
Yerel işlemlerin veya zamanlamanın geçici ağ bağlantısının geçici olarak kesilmesi gibi geçici farklılıklara neden olduğu durumlarda bile, etkinlikler her zaman verilerin doğru durumunu yansıtır. |
Tek bir istemciden yapılan yazmalar her zaman sunucuya yazılır ve diğer kullanıcılara sırayla yayınlanır. |
Değer etkinlikleri her zaman en son tetiklenir ve anlık görüntü alınmadan önce gerçekleşen diğer etkinliklere ait güncellemeleri içereceği garanti edilir. |
Değer etkinlikleri 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 Çağırmaları Ayırma
Geri çağırmalar, aşağıdaki gibi etkinlik türü ve kaldırılacak 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()
öğesine bir kapsam bağlamı ilettiyseniz geri çağırmayı ayırırken bu bağlamın iletilmesi gerekir:
Java
// Not applicable for Java
Node.js
ref.off('value', originalCallback, ctx);
Bir konumdaki tüm geri çağırmaları 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 Okuma
Bazı durumlarda, bir geri çağırmanın bir kez çağrılması, ardından hemen kaldırılması yararlı olabilir. Bu işlemi 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 });
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, verileri çeşitli faktörlere göre seçerek alabilirsiniz. Veritabanınızda bir sorgu oluşturmaya şu sıralama işlevlerinden birini kullanarak verilerinizin nasıl sıralanmasını istediğinizi belirterek başlarsınız: orderByChild()
, orderByKey()
veya orderByValue()
. Daha sonra, karmaşık sorgular yürütmek için bunları beş farklı yöntemle birleştirebilirsiniz: limitToFirst()
, limitToLast()
, startAt()
, endAt()
ve equalTo()
.
Firebase'de hepimiz dinozorların çok havalı olduğunu düşündüğünden Firebase veritabanınızdaki verileri nasıl sorgulayabileceğinizi göstermek için dinozorlarla ilgili örnek 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ıralayabilmek için ilgili anahtarı orderByChild()
öğesine iletebilirsiniz. Ö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'); });
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:"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 düğümler null
değeriyle sıralanır, yani sıralamada ilk sırada gelir. Verilerin nasıl sıralandığıyla ilgili ayrıntılar için Veriler Nasıl Sıralanır? bölümüne bakın.
Sorgular, yalnızca bir seviye alttaki alt öğeler yerine derinlemesine iç içe yerleştirilmiş alt öğelere göre de sıralanabilir. Bu, 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()
aynı sorguda birden çok kez çağrıldığında hata oluşur.
Anahtara göre sıralama
Ayrıca, orderByKey()
yöntemini kullanarak düğümleri anahtarlarına göre sıralayabilirsiniz. Aşağıdaki örnekte tüm dinozorlar alfabetik olarak sıralanmıştı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. Dinozorlarla ilgili bir dinozor yarışması olduğunu 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 Sıralanır? bölümüne bakın.
Karmaşık Sorgular
Verilerinizin nasıl sıralandığı artık net bir şekilde anlaşıldığına 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şlemi için senkronize edilecek maksimum alt öğe sayısını belirlemek amacıyla kullanılır. 100'lük bir sınır belirlerseniz başlangıçta en fazla 100 child_added
etkinliği alırsınız. Veritabanınızda 100'den az mesaj depolanıyorsa her mesaj için bir child_added
etkinliği tetiklenir. Ancak 100'den fazla mesajınız varsa bu mesajlardan yalnızca 100 tanesi için child_added
etkinliği alırsınız. Bunlar, limitToFirst()
kullanıyorsanız sıralanmış ilk 100 mesaj veya limitToLast()
kullanıyorsanız sıralanmış son 100 mesajdır. Öğeler değiştikçe, sorguyu giren öğeler için child_added
etkinlik ve onu bırakan öğeler için child_removed
etkinlik alırsınız. Böylece toplam sayı 100'de kalır.
Dinozor bilgileri veritabanını ve orderByChild()
yardımıyla 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)
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()) }
Veritabanında ikiden az dinozor bulunmadığı sürece child_added
geri çağırma işlemi tam olarak iki kez tetiklenir. Ayrıca, veritabanına eklenen her yeni ve daha ağır dinozorlar için ateşlenir.
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 ikiden az dinozor bulunmadığı sürece child_added
geri çağırma işlemi tam olarak iki kez tetiklenir. Ayrıca, ilk iki dinozordan biri veritabanından kaldırılırsa tekrar etkinleşir, çünkü yeni bir dinozor artık ikinci en kısa dinozor olur. 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. En yüksek puanlı 3 dinozor dinozorunu içeren bir skor tablosu oluşturmak isterseniz, 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()
kullandığınızda sorgularınız için rastgele başlangıç ve bitiş noktaları seçebilirsiniz. Örneğin, en az üç metre uzunluğundaki tüm dinozorları bulmak istiyorsanız orderByChild()
ve startAt()
değerlerini 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)
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()) }
Sözlüksel olarak isimleri Pterodaktilden ö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); });
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()) }
Sorgunuzun her iki ucunu da sınırlamak için startAt()
ve endAt()
değerlerini birleştirebilirsiniz. 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. Diğer aralık sorgularında olduğu gibi, eşleşen her alt düğüm için tetiklenir. Örneğin, 25 metre yüksekliğindeki 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)
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, 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')
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.
Alt Öğeye göre sipariş
orderByChild()
kullanılırken belirtilen alt anahtarı içeren veriler aşağıdaki gibi sıralanır:
- Belirtilen alt anahtar için
null
değerine sahip alt öğeler önce gelir. - Belirtilen alt anahtar için
false
değerine sahip alt öğeler bir sonraki bölümde gelir. Birden çok alt öğeninfalse
değeri varsa bunlar anahtara göre sözlüğe göre sıralanır. - Belirtilen alt anahtar için
true
değerine sahip alt öğeler bir sonraki bölümde gelir. Birden fazla alt öğenin değeritrue
ise bu alt öğeler sözlükte anahtara göre sıralanır. - Sayısal değere sahip olan alt öğeler, artan düzende sıralanmış olarak sırada gelir. Belirtilen alt düğüm için aynı sayısal değere sahip birden çok alt öğe varsa bunlar anahtara göre sıralanır.
- Dizeler sayılardan sonra gelir ve artan düzende sözlüksel olarak sıralanır. Belirtilen alt düğüm için birden fazla alt öğe aynı değere sahipse bunlar sözlükçe anahtara göre sıralanır.
- Nesneler en sondadır ve sözlük anlamında anahtara göre artan düzende sıralanır.
anahtara göre sipariş
Verilerinizi sıralamak için orderByKey()
kullanılırken veriler aşağıdaki gibi anahtara göre artan sırada döndürülür. Anahtarların yalnızca dizelerden oluşabileceğini unutmayın.
- 32 bit tam sayı olarak ayrıştırılabilen bir anahtara sahip alt öğeler, artan düzende sıralanmış olarak ilk sırada gelir.
- Anahtarları sırada dize değeri olan alt öğeler, sözlüğe göre artan düzende sıralanır.
siparişByValue
orderByValue()
kullanılırken alt öğeler değerlerine göre sıralanır. Belirtilen alt anahtarın değeri yerine düğümün değerinin kullanılması dışında sıralama ölçütü orderByChild()
ile aynıdır.