पुन: प्राप्त डेटा

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

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

शुरू करना

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

जावा
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());
  }
});
नोड.जेएस
// 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);
}); 
अजगर
# 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 है। पायथन में get() विधि सीधे डेटा का पायथन प्रतिनिधित्व करती है। गो में Get() फ़ंक्शन डेटा को किसी दिए गए डेटा संरचना में अनमार्शल करता है।

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

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

मूल्य

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

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

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

अगर आप अपने ब्लॉगिंग ऐप में जोड़े गए प्रत्येक नए पोस्ट पर केवल डेटा पुनर्प्राप्त करना चाहते हैं, तो आप child_added का उपयोग कर सकते हैं:

जावा
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) {}
});
नोड.जेएस
// 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 का उपयोग कर सकते हैं:

जावा
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) {}
});
नोड.जेएस
// 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 के संयोजन के साथ प्रयोग किया जाता है। इवेंट कॉलबैक में दिए गए स्नैपशॉट में हटाए गए बच्चे के लिए डेटा होता है।

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

जावा
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) {}
});
नोड.जेएस
// 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 इवेंट का उपयोग ऑर्डर किए गए डेटा के साथ काम करते समय किया जाता है, जिसे अगले सेक्शन में कवर किया गया है।

घटना की गारंटी

फायरबेस डेटाबेस घटनाओं के संबंध में कई महत्वपूर्ण गारंटी देता है:

डाटाबेस घटना की गारंटी
स्थानीय स्थिति में परिवर्तन होने पर ईवेंट हमेशा ट्रिगर किए जाएँगे।
घटनाएँ हमेशा अंततः डेटा की सही स्थिति को दर्शाती हैं, यहां तक ​​​​कि उन मामलों में भी जहां स्थानीय संचालन या समय अस्थायी अंतर पैदा करते हैं, जैसे कि नेटवर्क कनेक्शन के अस्थायी नुकसान में।
एक क्लाइंट से लिखे गए लेखन को हमेशा सर्वर पर लिखा जाएगा और क्रम में अन्य उपयोगकर्ताओं को प्रसारित किया जाएगा।
वैल्यू इवेंट्स हमेशा आखिरी ट्रिगर होते हैं और स्नैपशॉट लेने से पहले हुई किसी भी अन्य घटनाओं से अपडेट होने की गारंटी दी जाती है।

चूंकि मूल्य घटनाएं हमेशा अंत में ट्रिगर होती हैं, निम्न उदाहरण हमेशा काम करेगा:

जावा
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) {}
});
नोड.जेएस
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);
});

कॉलबैक को अलग करना

ईवेंट प्रकार और हटाए जाने वाले कॉलबैक फ़ंक्शन को निर्दिष्ट करके कॉलबैक हटा दिए जाते हैं, जैसे कि:

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

// Remove listener
ref.removeEventListener(listener);
नोड.जेएस
ref.off('value', originalCallback);

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

जावा
// Not applicable for Java
नोड.जेएस
ref.off('value', originalCallback, ctx);

यदि आप किसी स्थान पर सभी कॉलबैक हटाना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

जावा
// No Java equivalent, listeners must be removed individually.
नोड.जेएस
// Remove all value callbacks
ref.off('value');

// Remove all callbacks of any type
ref.off();

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

कुछ मामलों में कॉलबैक के लिए एक बार कॉल करना और फिर तुरंत हटा देना उपयोगी हो सकता है। हमने इसे आसान बनाने के लिए एक सहायक कार्य बनाया है:

जावा
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    // ...
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    // ...
  }
});
नोड.जेएस
ref.once('value', (data) => {
  // do some stuff once
});
अजगर
# 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)
}

डेटा क्वेरी करना

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

जावा
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.");
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');

ref.orderByChild('height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
अजगर
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
    }
  }
}

अब ऊंचाई पूछने के लिए, आप एक कुंजी के बजाय ऑब्जेक्ट के पूर्ण पथ का उपयोग कर सकते हैं:

जावा
dinosaursRef.orderByChild("dimensions/height").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    // ...
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByChild('dimensions/height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
अजगर
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() विधि का उपयोग करके नोड्स को उनकी कुंजी द्वारा भी ऑर्डर कर सकते हैं। निम्न उदाहरण सभी डायनासोर को वर्णानुक्रम में पढ़ता है:

जावा
dinosaursRef.orderByKey().addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
var ref = db.ref('dinosaurs');
ref.orderByKey().on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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
  }
}

डायनासोर को उनके स्कोर से क्रमबद्ध करने के लिए, आप निम्न क्वेरी बना सकते हैं:

जावा
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());
  }

  // ...
});
नोड.जेएस
const scoresRef = db.ref('scores');
scoresRef.orderByValue().on('value', (snapshot) => {
  snapshot.forEach((data) => {
    console.log('The ' + data.key + ' dinosaur\'s score is ' + data.val());
  });
});
अजगर
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() का उपयोग करके, आप दो सबसे भारी डायनासोर पा सकते हैं:

जावा
dinosaursRef.orderByChild("weight").limitToLast(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByChild('weight').limitToLast(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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 कॉलबैक को दो बार ट्रिगर किया जाता है। यह डेटाबेस में जोड़े जाने वाले हर नए, भारी डायनासोर के लिए भी निकाल दिया जाएगा। पायथन में, क्वेरी सीधे एक OrderedDict है जिसमें दो सबसे भारी डायनासोर होते हैं।

इसी प्रकार, आप limitToFirst() का उपयोग कर दो सबसे छोटे डायनासोर पा सकते हैं:

जावा
dinosaursRef.orderByChild("weight").limitToFirst(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByChild('height').limitToFirst(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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 कॉलबैक को दो बार ट्रिगर किया जाता है। यदि डेटाबेस से पहले दो डायनासोरों में से एक को हटा दिया जाता है, तो यह फिर से निकाल दिया जाएगा, क्योंकि एक नया डायनासोर अब दूसरा सबसे छोटा डायनासोर होगा। पायथन में, क्वेरी सीधे एक OrderedDict है जिसमें सबसे छोटा डायनासोर होता है।

आप orderByValue() के साथ सीमा प्रश्न भी कर सकते हैं। यदि आप शीर्ष 3 उच्चतम स्कोरिंग डिनो स्पोर्ट्स डायनासोर के साथ एक लीडरबोर्ड बनाना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

जावा
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());
  }

  // ...
});
नोड.जेएस
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());
  });
});
अजगर
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() को जोड़ सकते हैं:

जावा
dinosaursRef.orderByChild("height").startAt(3).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByChild('height').startAt(3).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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 lexicographically से पहले आते हैं:

जावा
dinosaursRef.orderByKey().endAt("pterodactyl").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByKey().endAt('pterodactyl').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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() को जोड़ सकते हैं। निम्नलिखित उदाहरण उन सभी डायनासोरों को ढूंढता है जिनका नाम "बी" अक्षर से शुरू होता है:

जावा
dinosaursRef.orderByKey().startAt("b").endAt("b\uf8ff").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
var ref = db.ref('dinosaurs');
ref.orderByKey().startAt('b').endAt('b\uf8ff').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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 मीटर लंबे सभी डायनासोर को खोजने के लिए निम्न क्वेरी का उपयोग कर सकते हैं:

जावा
dinosaursRef.orderByChild("height").equalTo(25).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
नोड.जेएस
const ref = db.ref('dinosaurs');
ref.orderByChild('height').equalTo(25).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
अजगर
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())
}

श्रेणी प्रश्न तब भी उपयोगी होते हैं जब आपको अपने डेटा को पृष्ठांकित करने की आवश्यकता होती है।

यह सब एक साथ डालें

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

जावा
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) {
    // ...
  }
});
नोड.जेएस
  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');
      }
    });
});
अजगर
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

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

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

orderByKey

अपने डेटा को सॉर्ट करने के लिए orderByKey() का उपयोग करते समय, डेटा को आरोही क्रम में कुंजी द्वारा निम्नानुसार लौटाया जाता है। ध्यान रखें कि कुंजियाँ केवल तार हो सकती हैं।

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

ऑर्डरबायवैल्यू

orderByValue() का उपयोग करते समय, बच्चों को उनके मूल्य द्वारा आदेश दिया जाता है। ऑर्डर करने का मानदंड orderByChild() के समान है, नोड के मान को छोड़कर निर्दिष्ट चाइल्ड कुंजी के मान के बजाय उपयोग किया जाता है।