डेटा वापस लाया जा रहा है

इस दस्तावेज़ में, डेटाबेस का डेटा वापस पाने, डेटा को क्रम से लगाने, और डेटा पर आसान क्वेरी करने के बारे में बुनियादी जानकारी दी गई है. एडमिन SDK में डेटा वापस पाने की प्रोसेस, अलग-अलग प्रोग्रामिंग भाषाओं में थोड़े अलग तरीके से की जाती है.

  1. एसिंक्रोनस लिसनर: Firebase Realtime Database में स्टोर किया गया डेटा, डेटाबेस रेफ़रंस में एसिंक्रोनस लिसनर जोड़कर लिया जाता है. डेटा की शुरुआती स्थिति के लिए, Listener को एक बार ट्रिगर किया जाता है और फिर डेटा में बदलाव होने पर, उसे फिर से ट्रिगर किया जाता है. इवेंट लिसनर को कई अलग-अलग टाइप के इवेंट मिल सकते हैं. डेटा वापस पाने का यह मोड, Java, Node.js, और Python एडमिन SDK टूल में काम करता है.
  2. रीड को ब्लॉक करना: Firebase Realtime Database में सेव किए गए डेटा को, डेटाबेस रेफ़रंस पर ब्लॉकिंग का तरीका इस्तेमाल करके हासिल किया जाता है. इससे रेफ़रंस में सेव किया गया डेटा मिलता है. हर मेथड कॉल एक बार में किया जाता है. इसका मतलब है कि SDK, डेटा के बाद के अपडेट को सुनने वाले किसी भी कॉलबैक को रजिस्टर नहीं करता. डेटा वापस पाने का यह मॉडल, Python और Go Admin SDKs में काम करता है.

शुरू करें

Firebase डेटाबेस से डेटा पढ़ने का तरीका समझने के लिए, पिछले लेख में दिए गए ब्लॉगिंग के उदाहरण पर फिर से जाएं. याद रखें कि उदाहरण के तौर पर दिए गए ऐप्लिकेशन की ब्लॉग पोस्ट, डेटाबेस के यूआरएल https://docs-examples.firebaseio.com/server/saving-data/fireblog/post.json पर सेव होती हैं. अपनी पोस्ट का डेटा पढ़ने के लिए, ये काम किए जा सकते हैं:

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())
शुरू करें
// 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)
}

ऊपर दिया गया कोड चलाने पर, आपको एक ऑब्जेक्ट दिखेगा. इसमें कंसोल में लॉग की गई आपकी सभी पोस्ट शामिल होंगी. Node.js और Java के मामले में, आपके डेटाबेस रेफ़रंस में नया डेटा जोड़े जाने पर, लिसनर फ़ंक्शन को कॉल किया जाता है. इसके लिए, आपको कोई अतिरिक्त कोड लिखने की ज़रूरत नहीं है.

Java और Node.js में, कॉलबैक फ़ंक्शन को एक DataSnapshot मिलता है, जो डेटा का स्नैपशॉट होता है. स्नैपशॉट, किसी खास समय पर किसी डेटाबेस रेफ़रंस में मौजूद डेटा की इमेज होती है. किसी स्नैपशॉट पर val() / getValue() को कॉल करने से, डेटा को भाषा के हिसाब से ऑब्जेक्ट के तौर पर दिखाया जाता है. अगर रेफ़रंस की जगह पर कोई डेटा मौजूद नहीं है, तो स्नैपशॉट की वैल्यू null होती है. Python में get() तरीका, डेटा को सीधे Python में दिखाता है. Go में Get() फ़ंक्शन, डेटा को दिए गए डेटा स्ट्रक्चर में अनमार्शल करता है.

ध्यान दें कि ऊपर दिए गए उदाहरण में, हमने value इवेंट टाइप का इस्तेमाल किया है. यह Firebase डेटाबेस रेफ़रंस के पूरे कॉन्टेंट को पढ़ता है. भले ही, डेटा में सिर्फ़ एक बदलाव हुआ हो. value, यहां दिए गए पांच अलग-अलग इवेंट टाइप में से एक है. इसका इस्तेमाल, डेटाबेस से डेटा पढ़ने के लिए किया जा सकता है.

Java और Node.js में इवेंट टाइप पढ़ना

मान

value इवेंट का इस्तेमाल, किसी डेटाबेस पाथ पर मौजूद कॉन्टेंट का स्टैटिक स्नैपशॉट पढ़ने के लिए किया जाता है. यह स्नैपशॉट, पढ़ने के इवेंट के समय मौजूद होता है. यह शुरुआती डेटा के साथ एक बार ट्रिगर होता है. इसके बाद, हर बार डेटा में बदलाव होने पर ट्रिगर होता है. इवेंट कॉलबैक को एक स्नैपशॉट भेजा जाता है, जिसमें उस जगह का सारा डेटा होता है. इसमें बच्चे का डेटा भी शामिल होता है. ऊपर दिए गए कोड के उदाहरण में, value ने आपके ऐप्लिकेशन में मौजूद सभी ब्लॉग पोस्ट दिखाई हैं. जब भी कोई नई ब्लॉग पोस्ट जोड़ी जाएगी, तो कॉलबैक फ़ंक्शन सभी पोस्ट दिखाएगा.

बच्चे को जोड़ा गया

आम तौर पर, child_added इवेंट का इस्तेमाल डेटाबेस से आइटम की सूची हासिल करते समय किया जाता है. value, जगह के पूरे कॉन्टेंट को दिखाता है. इसके उलट, child_added हर मौजूदा चाइल्ड के लिए एक बार ट्रिगर होता है. इसके बाद, तय किए गए पाथ में हर बार नया चाइल्ड जोड़ने पर, यह फिर से ट्रिगर होता है. इवेंट कॉलबैक को एक स्नैपशॉट भेजा जाता है, जिसमें नए बच्चे का डेटा होता है. क्रम से लगाने के लिए, इसमें एक दूसरा आर्ग्युमेंट भी पास किया जाता है. इसमें पिछले चाइल्ड की कुंजी होती है.

अगर आपको अपने ब्लॉगिंग ऐप्लिकेशन में जोड़ी गई हर नई पोस्ट का सिर्फ़ डेटा वापस पाना है, तो child_added का इस्तेमाल करें:

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

इस उदाहरण में, स्नैपशॉट में किसी ब्लॉग पोस्ट वाला ऑब्जेक्ट होगा. SDK टूल, पोस्ट की वैल्यू को वापस लाकर उन्हें ऑब्जेक्ट में बदल देता है. इसलिए, आपके पास पोस्ट के लेखक और टाइटल प्रॉपर्टी को ऐक्सेस करने का विकल्प होता है. इसके लिए, आपको क्रमशः author और title को कॉल करना होगा. आपके पास दूसरे prevChildKey आर्ग्युमेंट से, पिछले पोस्ट आईडी का ऐक्सेस भी होता है.

चाइल्ड बदल गया

जब भी किसी चाइल्ड नोड में बदलाव किया जाता है, तो child_changed इवेंट ट्रिगर होता है. इसमें चाइल्ड नोड के वंशजों में किए गए सभी बदलाव भी शामिल हैं. आम तौर पर, इसका इस्तेमाल आइटम की सूची में हुए बदलावों के जवाब में, child_added और child_removed के साथ किया जाता है. इवेंट कॉलबैक में भेजे गए स्नैपशॉट में, चाइल्ड के लिए अपडेट किया गया डेटा होता है.

ब्लॉग पोस्ट में बदलाव होने पर, अपडेट किया गया डेटा पढ़ने के लिए child_changed का इस्तेमाल किया जा सकता है:

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

बच्चे को हटाना

child_removed इवेंट तब ट्रिगर होता है, जब किसी बच्चे को तुरंत हटाया जाता है. आम तौर पर, इसका इस्तेमाल child_added और child_changed के साथ किया जाता है. इवेंट कॉलबैक में भेजे गए स्नैपशॉट में, हटाए गए बच्चे का डेटा शामिल होता है.

ब्लॉग के उदाहरण में, मिटाई गई पोस्ट के बारे में सूचना को Console में लॉग करने के लिए, child_removed का इस्तेमाल किया जा सकता है:

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');
});

बच्चे को किसी दूसरी जगह ले जाया गया

child_moved इवेंट का इस्तेमाल, क्रम में लगाए गए डेटा के साथ काम करते समय किया जाता है. इस बारे में अगले सेक्शन में बताया गया है.

इवेंट की गारंटी

Firebase डेटाबेस, इवेंट से जुड़ी कई अहम गारंटी देता है:

डेटाबेस इवेंट की गारंटी
लोकल स्टेटस में बदलाव होने पर, इवेंट हमेशा ट्रिगर होंगे.
इवेंट में हमेशा डेटा की सही स्थिति दिखेगी. भले ही, स्थानीय ऑपरेशन या समय की वजह से कुछ समय के लिए अंतर दिखे. जैसे, नेटवर्क कनेक्शन कुछ समय के लिए बंद होने पर.
किसी एक क्लाइंट के लेख हमेशा सर्वर पर लिखे जाएंगे और अन्य उपयोगकर्ताओं को उनके क्रम में ब्रॉडकास्ट किए जाएंगे.
वैल्यू इवेंट हमेशा आखिर में ट्रिगर होते हैं. साथ ही, यह पक्का होता है कि उनमें ऐसे किसी भी इवेंट के अपडेट शामिल होंगे जो स्नैपशॉट लेने से पहले हुए थे.

वैल्यू इवेंट हमेशा आखिरी बार ट्रिगर किए जाते हैं. इसलिए, यहां दिया गया उदाहरण हमेशा काम करेगा:

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

कॉलबैक अलग किए जा रहे हैं

इवेंट टाइप और हटाए जाने वाले कॉलबैक फ़ंक्शन की जानकारी देकर, कॉलबैक हटाए जाते हैं. जैसे:

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

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

अगर आपने on() में स्कोप का संदर्भ पास किया है, तो कॉलबैक को अलग करते समय उसे पास करना होगा:

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

अगर आपको किसी जगह के लिए सभी कॉलबैक हटाने हैं, तो यह तरीका अपनाएं:

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

डेटा को एक बार पढ़ना

कुछ मामलों में, कॉलबैक को एक बार कॉल करने और तुरंत हटाने से फ़ायदा हो सकता है. इस प्रक्रिया को आसान बनाने के लिए, हमने एक हेल्पर फ़ंक्शन बनाया है:

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())
शुरू करें
// 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)
}

डेटा के बारे में क्वेरी करना

Firebase डेटाबेस क्वेरी की मदद से, अलग-अलग वजहों के आधार पर डेटा को चुनिंदा तौर पर वापस पाया जा सकता है. अपने डेटाबेस में क्वेरी बनाने के लिए, आपको यह तय करना होगा कि आपको अपने डेटा को किस क्रम में लगाना है. इसके लिए, orderByChild(), orderByKey() या orderByValue() में से किसी एक फ़ंक्शन का इस्तेमाल करें. इसके बाद, इनका इस्तेमाल पांच अन्य तरीकों के साथ करके, जटिल क्वेरी की जा सकती हैं: limitToFirst(), limitToLast(), startAt(), endAt(), और equalTo().

Firebase में हम सभी को डायनासोर बहुत पसंद हैं. इसलिए, हम डायनासोर के बारे में जानकारी वाले सैंपल डेटाबेस के स्निपेट का इस्तेमाल करके, यह दिखाएंगे कि अपने Firebase डेटाबेस में डेटा की क्वेरी कैसे की जा सकती है.:

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

डेटा को तीन तरीकों से क्रम में लगाया जा सकता है: चाइल्ड की-, की- या वैल्यू के हिसाब से. डेटाबेस की बुनियादी क्वेरी, इनमें से किसी एक क्रम सेट करने वाले फ़ंक्शन से शुरू होती है. इन सभी फ़ंक्शन के बारे में नीचे बताया गया है.

किसी खास चाइल्ड कुंजी के हिसाब से क्रम में लगाना

किसी सामान्य चाइल्ड कुंजी के हिसाब से नोड का क्रम तय किया जा सकता है. इसके लिए, उस कुंजी को orderByChild() में पास करें. उदाहरण के लिए, ऊंचाई के हिसाब से क्रम में लगाए गए सभी डायनासॉर को पढ़ने के लिए, ये काम किए जा सकते हैं:

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))
शुरू करें
// 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)
}

जिस नोड में वह चाइल्ड की-वैल्यू नहीं होती जिस पर हम क्वेरी कर रहे हैं उसे null की वैल्यू के साथ क्रम से लगाया जाता है. इसका मतलब है कि वह क्रम में सबसे पहले आएगा. डेटा को क्रम से लगाने के तरीके के बारे में जानने के लिए, डेटा को क्रम से लगाने का तरीका सेक्शन देखें.

क्वेरी को एक लेवल नीचे मौजूद चाइल्ड के बजाय, नेस्ट किए गए चाइल्ड के हिसाब से भी क्रम में लगाया जा सकता है. यह तब फ़ायदेमंद होता है, जब आपके पास डीप नेस्ट किया गया डेटा इस तरह का हो:

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

अब ऊंचाई की क्वेरी करने के लिए, किसी एक कुंजी के बजाय ऑब्जेक्ट के पूरे पाथ का इस्तेमाल किया जा सकता है:

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))
शुरू करें
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)
}

क्वेरी को एक बार में सिर्फ़ एक कुंजी के हिसाब से क्रम में लगाया जा सकता है. एक ही क्वेरी पर orderByChild() को कई बार कॉल करने पर गड़बड़ी का मैसेज मिलता है.

बटन के हिसाब से क्रम से लगाना

orderByKey() तरीके का इस्तेमाल करके, नोड को उनकी कुंजियों के हिसाब से क्रम में लगाया जा सकता है. नीचे दिए गए उदाहरण में, सभी डायनासोर को वर्णमाला के क्रम में पढ़ा गया है:

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)
शुरू करें
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)

वैल्यू के हिसाब से क्रम से लगाना

orderByValue() तरीके का इस्तेमाल करके, नोड को उनकी चाइल्ड बटन की वैल्यू के हिसाब से क्रम में लगाया जा सकता है. मान लें कि डायनासोर एक स्पोर्ट्स प्रतियोगिता में हिस्सा ले रहे हैं और आप उनके स्कोर को इस फ़ॉर्मैट में ट्रैक कर रहे हैं:

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

डायनासॉर को उनके स्कोर के हिसाब से क्रम में लगाने के लिए, यह क्वेरी बनाएं:

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))
शुरू करें
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() का इस्तेमाल करते समय null, बूलियन, स्ट्रिंग, और ऑब्जेक्ट वैल्यू को किस तरह क्रम से लगाया जाता है, इस बारे में जानने के लिए, डेटा को क्रम में लगाने का तरीका सेक्शन देखें.

जटिल क्वेरी

अब यह साफ़ हो गया है कि आपका डेटा किस क्रम में है. ज़्यादा जटिल क्वेरी बनाने के लिए, यहां बताए गए सीमा या रेंज के तरीकों का इस्तेमाल किया जा सकता है.

क्वेरी की सीमा तय करें

limitToFirst() और limitToLast() क्वेरी का इस्तेमाल, किसी कॉलबैक के लिए सिंक किए जाने वाले बच्चों की ज़्यादा से ज़्यादा संख्या सेट करने के लिए किया जाता है. अगर आपने 100 की सीमा सेट की है, तो आपको शुरू में सिर्फ़ 100 child_added इवेंट मिलेंगे. अगर आपके डेटाबेस में 100 से कम मैसेज सेव हैं, तो हर मैसेज के लिए child_added इवेंट ट्रिगर होगा. हालांकि, अगर आपके पास 100 से ज़्यादा मैसेज हैं, तो आपको उनमें से सिर्फ़ 100 मैसेज के लिए child_added इवेंट मिलेगा. अगर limitToFirst() का इस्तेमाल किया जा रहा है, तो ये क्रम में लगाए गए पहले 100 मैसेज हैं. अगर limitToLast() का इस्तेमाल किया जा रहा है, तो ये क्रम में लगाए गए आखिरी 100 मैसेज हैं. आइटम बदलने पर, आपको क्वेरी में शामिल होने वाले आइटम के लिए child_added इवेंट और क्वेरी से बाहर निकलने वाले आइटम के लिए child_removed इवेंट मिलेंगे, ताकि कुल संख्या 100 पर बनी रहे.

डायनासोर के बारे में जानकारी वाले डेटाबेस और orderByChild() का इस्तेमाल करके, सबसे ज़्यादा वज़न वाले दो डायनासोर के बारे में पता लगाया जा सकता है:

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)
शुरू करें
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 कॉलबैक ठीक दो बार ट्रिगर होता है. ऐसा तब तक होता है, जब तक कि डेटाबेस में दो से कम डायनासोर सेव न किए गए हों. यह डेटाबेस में जोड़े जाने वाले हर नए और भारी डायनासॉर के लिए भी काम करेगा. Python में, क्वेरी सीधे ऐसा OrderedDict दिखाती है जिसमें दो सबसे भारी डायनासॉर होते हैं.

इसी तरह, limitToFirst() का इस्तेमाल करके, सबसे छोटे दो डायनासोर ढूंढे जा सकते हैं:

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)
शुरू करें
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 कॉलबैक दो बार ट्रिगर होता है. हालांकि, ऐसा तब तक नहीं होता, जब तक डेटाबेस में दो से कम डायनासोर सेव न हों. अगर डेटाबेस से पहले दो डायनासोर में से किसी एक को हटाया जाता है, तो यह फ़ंक्शन फिर से ट्रिगर हो जाएगा. ऐसा इसलिए होगा, क्योंकि अब नया डायनासोर सबसे छोटा होगा. Python में, क्वेरी सीधे ऐसा OrderedDict दिखाती है जिसमें सबसे छोटे डायनासोर होते हैं.

orderByValue() का इस्तेमाल करके भी क्वेरी की सीमा तय की जा सकती है. अगर आपको सबसे ज़्यादा स्कोर करने वाले तीन डायनासोर के साथ लीडरबोर्ड बनाना है, तो यह तरीका अपनाएं:

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))
शुरू करें
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)
}

रेंज क्वेरी

startAt(), endAt(), और equalTo() का इस्तेमाल करके, अपनी क्वेरी के लिए, शुरुआत और आखिर के पॉइंट को अपनी पसंद के मुताबिक चुना जा सकता है. उदाहरण के लिए, अगर आपको ऐसे सभी डायनासोर ढूंढने हैं जो कम से कम तीन मीटर ऊंचे हैं, तो orderByChild() और 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)
शुरू करें
ref := client.NewRef("dinosaurs")

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

endAt() का इस्तेमाल करके, उन सभी डायनासोर को ढूंढा जा सकता है जिनके नाम, लिक्सिकोग्राफ़ी के हिसाब से Pterodactyl से पहले आते हैं:

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)
शुरू करें
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())
}

क्वेरी के दोनों छोर सीमित करने के लिए, startAt() और endAt() को एक साथ इस्तेमाल किया जा सकता है. इस उदाहरण में, ऐसे सभी डायनासोर ढूंढे गए हैं जिनका नाम "b" अक्षर से शुरू होता है:

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)
शुरू करें
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() तरीके की मदद से, एग्ज़ैक्ट मैच के आधार पर फ़िल्टर किया जा सकता है. अन्य रेंज क्वेरी की तरह ही, यह मेल खाने वाले हर चाइल्ड नोड के लिए फ़ायर होगा. उदाहरण के लिए, 25 मीटर ऊंचे सभी डायनासोर ढूंढने के लिए, यहां दी गई क्वेरी का इस्तेमाल किया जा सकता है:

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)
शुरू करें
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())
}

रेंज क्वेरी तब भी काम की होती हैं, जब आपको अपने डेटा को पेज पर दिखाना हो.

जानकारी को एक जगह इकट्ठा किया जा रहा है

जटिल क्वेरी बनाने के लिए, इन सभी तकनीकों को एक साथ इस्तेमाल किया जा सकता है. उदाहरण के लिए, आपको उस डायनासॉर का नाम मिल सकता है जो स्टेगासॉरस से थोड़ा छोटा है:

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')
शुरू करें
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")
}

डेटा को क्रम से लगाने का तरीका

यह सेक्शन बताता है कि ऑर्डर करने के चार फ़ंक्शन में से हर एक का इस्तेमाल करते समय, आपके डेटा को कैसे ऑर्डर किया जाता है.

ऑर्डर बायचाइल्ड

orderByChild() का इस्तेमाल करते समय, जिस डेटा में चाइल्ड पासकोड शामिल होता है उसे इस तरह क्रम से लगाया जाता है:

  1. किसी खास चाइल्ड की-वर्ड के लिए null वैल्यू वाले बच्चे पहले दिखते हैं.
  2. तय की गई चाइल्ड कुंजी के लिए false वैल्यू वाले बच्चे इसके बाद आते हैं. अगर कई बच्चों की वैल्यू false है, तो उन्हें लेक्सिकोग्राफ़िक तौर पर कुंजी के हिसाब से क्रम में लगाया जाता है.
  3. इसके बाद, तय की गई चाइल्ड कुंजी के लिए true वैल्यू वाले बच्चे आते हैं. अगर एक से ज़्यादा चाइल्ड एलिमेंट की वैल्यू true है, तो उन्हें कीवर्ड के हिसाब से, वर्णमाला के क्रम में क्रम से लगाया जाता है.
  4. इसके बाद, संख्या वाली वैल्यू वाले बच्चे आते हैं. इन्हें बढ़ते क्रम में लगाया जाता है. अगर किसी चाइल्ड नोड के लिए, एक से ज़्यादा चाइल्ड की संख्या वाली वैल्यू एक जैसी है, तो उन्हें कीवर्ड के हिसाब से क्रम में लगाया जाता है.
  5. स्ट्रिंग, संख्याओं के बाद आती हैं और इन्हें बढ़ते क्रम में लेक्सिकोलॉजिकल तौर पर क्रम में लगाया जाता है. अगर कई चाइल्ड नोड में, चुने गए चाइल्ड नोड के लिए एक ही वैल्यू है, तो उन्हें कीवर्ड के हिसाब से, वर्णमाला के क्रम में लगाया जाता है.
  6. ऑब्जेक्ट आखिर में आते हैं और उन्हें कीवर्ड के हिसाब से, बढ़ते क्रम में लगाया जाता है.

orderByKey

अपने डेटा को क्रम से लगाने के लिए orderByKey() का इस्तेमाल करने पर, डेटा को कुंजी के हिसाब से, बढ़ते क्रम में दिखाया जाता है. ध्यान रखें कि कुंजियां सिर्फ़ स्ट्रिंग हो सकती हैं.

  1. जिन बच्चों की कुंजी को 32-बिट के पूर्णांक के तौर पर पार्स किया जा सकता है वे सबसे पहले दिखते हैं. साथ ही, उन्हें बढ़ते क्रम में क्रम से लगाया जाता है.
  2. जिन बच्चों में स्ट्रिंग वैल्यू के आगे मुख्य होता है उन्हें बढ़ते क्रम में लेक्सिकोग्राफ़िक रूप से रखा जाता है.

ऑर्डर की रकम

orderByValue() का इस्तेमाल करने पर, बच्चों को उनकी वैल्यू के हिसाब से क्रम में लगाया जाता है. क्रम से लगाने की शर्तें, orderByChild() में बताई गई शर्तों जैसी ही हैं. हालांकि, किसी तय चाइल्ड की वैल्यू के बजाय, नोड की वैल्यू का इस्तेमाल किया जाता है.