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

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

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

शुरू करना

आइए फ़ायरबेस डेटाबेस से डेटा पढ़ने का तरीका समझने के लिए पिछले लेख के ब्लॉगिंग उदाहरण को फिर से देखें। याद रखें कि उदाहरण ऐप में ब्लॉग पोस्ट डेटाबेस 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() , या orderByValue() । फिर आप जटिल प्रश्नों को संचालित करने के लिए इन्हें पांच अन्य तरीकों के साथ जोड़ सकते हैं: limitToFirst() , limitToLast() , startAt() , endAt() , और equalTo()

चूँकि फायरबेस पर हम सभी सोचते हैं कि डायनासोर बहुत अच्छे हैं, हम डायनासोर तथ्यों के एक नमूना डेटाबेस से एक स्निपेट का उपयोग करके प्रदर्शित करेंगे कि आप अपने फायरबेस डेटाबेस में डेटा को कैसे क्वेरी कर सकते हैं।

{
  "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() का उपयोग कर सकते हैं जिनके नाम लेक्सिकोग्राफ़िक रूप से टेरोडैक्टाइल से पहले आते हैं:

जावा
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

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