Android पर डेटा की सूचियों के साथ कार्य करें

यह दस्तावेज़ फायरबेस में डेटा की सूचियों के साथ काम करना शामिल करता है। फायरबेस डेटा को पढ़ने और लिखने की मूल बातें जानने के लिए एंड्रॉइड पर डेटा पढ़ें और लिखें देखें।

एक डेटाबेस संदर्भ प्राप्त करें

डेटाबेस से डेटा पढ़ने और लिखने के लिए, आपको DatabaseReference का एक उदाहरण चाहिए:

Kotlin+KTX

private lateinit var database: DatabaseReference
// ...
database = Firebase.database.reference

Java

private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();

सूचियाँ पढ़ें और लिखें

डेटा की सूची में जोड़ें

बहुउपयोगकर्ता अनुप्रयोगों में किसी सूची में डेटा जोड़ने के लिए push() विधि का उपयोग करें। हर बार निर्दिष्ट फायरबेस संदर्भ में एक नया बच्चा जोड़ने पर push() विधि एक अद्वितीय कुंजी उत्पन्न करती है। सूची में प्रत्येक नए तत्व के लिए इन ऑटो-जेनरेट की गई कुंजियों का उपयोग करके, कई ग्राहक बिना लेखन विरोध के एक ही समय में बच्चों को एक ही स्थान पर जोड़ सकते हैं। push() द्वारा उत्पन्न अद्वितीय कुंजी टाइमस्टैम्प पर आधारित होती है, इसलिए सूची आइटम स्वचालित रूप से कालानुक्रमिक रूप से क्रमबद्ध होते हैं।

आप बच्चे की स्वत: जेनरेट की गई कुंजी का मूल्य प्राप्त करने या बच्चे के लिए सेट डेटा प्राप्त करने के लिए push() विधि द्वारा लौटाए गए नए डेटा के संदर्भ का उपयोग कर सकते हैं। push() संदर्भ पर getKey() कॉल करने से स्वतः-जनरेट की गई कुंजी का मान वापस आ जाता है।

आप अपनी डेटा संरचना को सरल बनाने के लिए इन स्वतः-जनित कुंजियों का उपयोग कर सकते हैं। अधिक जानकारी के लिए डेटा फैन-आउट उदाहरण देखें।

बच्चों की घटनाओं को सुनें

सूचियों के साथ काम करते समय, आपके एप्लिकेशन को एकल ऑब्जेक्ट के लिए उपयोग किए जाने वाले मूल्य इवेंट के बजाय चाइल्ड इवेंट को सुनना चाहिए।

किसी ऑपरेशन से नोड के बच्चों के साथ होने वाले विशिष्ट ऑपरेशनों के जवाब में चाइल्ड इवेंट ट्रिगर होते हैं जैसे कि push() विधि के माध्यम से जोड़ा गया एक नया बच्चा या updateChildren() विधि के माध्यम से अपडेट किया जा रहा बच्चा। इनमें से प्रत्येक एक साथ डेटाबेस में किसी विशिष्ट नोड में परिवर्तन सुनने के लिए उपयोगी हो सकता है।

DatabaseReference पर बच्चों की घटनाओं को सुनने के लिए, एक ChildEventListener संलग्न करें:

श्रोता इवेंट कॉलबैक विशिष्ट उपयोग
ChildEventListener onChildAdded() आइटमों की सूचियाँ पुनः प्राप्त करें या आइटमों की सूची में अतिरिक्त चीज़ों को सुनें। यह कॉलबैक प्रत्येक मौजूदा बच्चे के लिए एक बार ट्रिगर होता है और फिर हर बार निर्दिष्ट पथ में एक नया बच्चा जोड़ा जाता है। श्रोता को दिए गए DataSnapshot में नए बच्चे का डेटा होता है।
onChildChanged() किसी सूची में आइटमों में परिवर्तन सुनें. जब भी चाइल्ड नोड को संशोधित किया जाता है, तो यह ईवेंट सक्रिय हो जाता है, जिसमें चाइल्ड नोड के वंशजों में कोई भी संशोधन शामिल होता है। इवेंट श्रोता को दिए गए DataSnapshot में बच्चे के लिए अद्यतन डेटा होता है।
onChildRemoved() सूची से हटाए जा रहे आइटमों को सुनें। इवेंट कॉलबैक में पास किए गए DataSnapshot में हटाए गए बच्चे का डेटा होता है।
onChildMoved() ऑर्डर की गई सूची में आइटमों के क्रम में बदलावों को सुनें। यह ईवेंट तब ट्रिगर होता है जब onChildChanged() कॉलबैक किसी अपडेट द्वारा ट्रिगर होता है जो बच्चे के पुन: क्रम का कारण बनता है। इसका उपयोग उस डेटा के साथ किया जाता है जिसे orderByChild या orderByValue के साथ ऑर्डर किया गया है।

उदाहरण के लिए, एक सोशल ब्लॉगिंग ऐप किसी पोस्ट की टिप्पणियों में गतिविधि पर नज़र रखने के लिए इन तरीकों का एक साथ उपयोग कर सकता है, जैसा कि नीचे दिखाया गया है:

Kotlin+KTX

val childEventListener = object : ChildEventListener {
    override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildAdded:" + dataSnapshot.key!!)

        // A new comment has been added, add it to the displayed list
        val comment = dataSnapshot.getValue<Comment>()

        // ...
    }

    override fun onChildChanged(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildChanged: ${dataSnapshot.key}")

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so displayed the changed comment.
        val newComment = dataSnapshot.getValue<Comment>()
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onChildRemoved(dataSnapshot: DataSnapshot) {
        Log.d(TAG, "onChildRemoved:" + dataSnapshot.key!!)

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so remove it.
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onChildMoved(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildMoved:" + dataSnapshot.key!!)

        // A comment has changed position, use the key to determine if we are
        // displaying this comment and if so move it.
        val movedComment = dataSnapshot.getValue<Comment>()
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.w(TAG, "postComments:onCancelled", databaseError.toException())
        Toast.makeText(
            context,
            "Failed to load comments.",
            Toast.LENGTH_SHORT,
        ).show()
    }
}
databaseReference.addChildEventListener(childEventListener)

Java

ChildEventListener childEventListener = new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());

        // A new comment has been added, add it to the displayed list
        Comment comment = dataSnapshot.getValue(Comment.class);

        // ...
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so displayed the changed comment.
        Comment newComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so remove it.
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

        // A comment has changed position, use the key to determine if we are
        // displaying this comment and if so move it.
        Comment movedComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w(TAG, "postComments:onCancelled", databaseError.toException());
        Toast.makeText(mContext, "Failed to load comments.",
                Toast.LENGTH_SHORT).show();
    }
};
databaseReference.addChildEventListener(childEventListener);

मूल्यवान घटनाओं को सुनें

जबकि डेटा की सूचियों को पढ़ने के लिए ChildEventListener का उपयोग अनुशंसित तरीका है, ऐसी स्थितियाँ हैं जहाँ किसी सूची संदर्भ में ValueEventListener को संलग्न करना उपयोगी होता है।

डेटा की सूची में एक ValueEventListener संलग्न करने से डेटा की पूरी सूची एक DataSnapshot के रूप में वापस आ जाएगी, जिसे आप अलग-अलग बच्चों तक पहुंचने के लिए लूप कर सकते हैं।

यहां तक ​​कि जब क्वेरी के लिए केवल एक ही मिलान होता है, तब भी स्नैपशॉट एक सूची है; इसमें केवल एक आइटम शामिल है। आइटम तक पहुंचने के लिए, आपको परिणाम पर लूप करना होगा:

Kotlin+KTX

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (postSnapshot in dataSnapshot.children) {
            // TODO: handle the post
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
        // ...
    }
})

Java

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
});

यह पैटर्न तब उपयोगी हो सकता है जब आप अतिरिक्त onChildAdded ईवेंट सुनने के बजाय किसी सूची के सभी बच्चों को एक ही ऑपरेशन में लाना चाहते हैं।

श्रोताओं को अलग करें

आपके फायरबेस डेटाबेस संदर्भ पर removeEventListener() विधि को कॉल करके कॉलबैक हटा दिए जाते हैं।

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

पैरेंट श्रोता पर removeEventListener() कॉल करने से उसके चाइल्ड नोड्स पर पंजीकृत श्रोता स्वचालित रूप से नहीं हटते हैं; कॉलबैक को हटाने के लिए किसी भी चाइल्ड श्रोता पर removeEventListener() भी कॉल किया जाना चाहिए।

डेटा को सॉर्ट करना और फ़िल्टर करना

आप कुंजी, मूल्य या किसी बच्चे के मूल्य के आधार पर क्रमबद्ध डेटा को पुनः प्राप्त करने के लिए रीयलटाइम डेटाबेस Query क्लास का उपयोग कर सकते हैं। आप क्रमबद्ध परिणाम को विशिष्ट संख्या में परिणामों या कुंजियों या मानों की श्रेणी में फ़िल्टर भी कर सकते हैं।

डेटा क्रमबद्ध करें

क्रमबद्ध डेटा को पुनः प्राप्त करने के लिए, परिणामों को कैसे क्रमबद्ध किया जाता है यह निर्धारित करने के लिए ऑर्डर-बाय विधियों में से एक को निर्दिष्ट करके प्रारंभ करें:

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

आप एक समय में केवल एक ऑर्डर-बाय विधि का उपयोग कर सकते हैं। एक ही क्वेरी में ऑर्डर-बाय विधि को कई बार कॉल करने से त्रुटि उत्पन्न होती है।

निम्नलिखित उदाहरण दर्शाता है कि आप किसी उपयोगकर्ता की स्टार संख्या के आधार पर क्रमबद्ध शीर्ष पोस्ट की सूची कैसे प्राप्त कर सकते हैं:

Kotlin+KTX

// My top posts by number of stars
val myUserId = uid
val myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
    .orderByChild("starCount")

myTopPostsQuery.addChildEventListener(object : ChildEventListener {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
})

Java

// My top posts by number of stars
String myUserId = getUid();
Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
        .orderByChild("starCount");
myTopPostsQuery.addChildEventListener(new ChildEventListener() {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
});

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

orderByChild() विधि पर कॉल परिणामों को ऑर्डर करने के लिए चाइल्ड कुंजी निर्दिष्ट करती है। इस मामले में, पोस्ट को उनके संबंधित "starCount" चाइल्ड के मान के आधार पर क्रमबद्ध किया जाता है। यदि आपके पास इस तरह दिखने वाला डेटा है, तो क्वेरीज़ को नेस्टेड बच्चों द्वारा भी ऑर्डर किया जा सकता है:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

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

Kotlin+KTX

// Most viewed posts
val myMostViewedPostsQuery = databaseReference.child("posts")
    .orderByChild("metrics/views")
myMostViewedPostsQuery.addChildEventListener(object : ChildEventListener {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
})

Java

// Most viewed posts
Query myMostViewedPostsQuery = databaseReference.child("posts")
        .orderByChild("metrics/views");
myMostViewedPostsQuery.addChildEventListener(new ChildEventListener() {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
});

अन्य डेटा प्रकारों को कैसे ऑर्डर किया जाता है, इस बारे में अधिक जानकारी के लिए, क्वेरी डेटा को कैसे ऑर्डर किया जाता है देखें।

डेटा फ़िल्टर करना

डेटा फ़िल्टर करने के लिए, आप क्वेरी बनाते समय किसी भी सीमा या श्रेणी विधि को ऑर्डर-बाय विधि के साथ जोड़ सकते हैं।

तरीका प्रयोग
limitToFirst() परिणामों की क्रमबद्ध सूची की शुरुआत से लौटने के लिए आइटमों की अधिकतम संख्या निर्धारित करता है।
limitToLast() परिणामों की आदेशित सूची के अंत से लौटाए जाने वाले आइटमों की अधिकतम संख्या निर्धारित करता है।
startAt() चुनी गई ऑर्डर-बाय विधि के आधार पर निर्दिष्ट कुंजी या मान से अधिक या उसके बराबर आइटम लौटाएं।
startAfter() चुनी गई ऑर्डर-बाय विधि के आधार पर निर्दिष्ट कुंजी या मान से अधिक आइटम लौटाएं।
endAt() चुनी गई ऑर्डर-बाय विधि के आधार पर निर्दिष्ट कुंजी या मान से कम या उसके बराबर आइटम लौटाएं।
endBefore() चुनी गई ऑर्डर-बाय विधि के आधार पर निर्दिष्ट कुंजी या मूल्य से कम आइटम लौटाएं।
equalTo() चुनी गई ऑर्डर-बाय विधि के आधार पर निर्दिष्ट कुंजी या मान के बराबर आइटम लौटाएं।

ऑर्डर-बाय विधियों के विपरीत, आप एकाधिक सीमा या श्रेणी फ़ंक्शंस को जोड़ सकते हैं। उदाहरण के लिए, आप परिणामों को मानों की एक निर्दिष्ट सीमा तक सीमित करने के लिए startAt() और endAt() तरीकों को जोड़ सकते हैं।

यहां तक ​​कि जब क्वेरी के लिए केवल एक ही मिलान होता है, तब भी स्नैपशॉट एक सूची है; इसमें केवल एक आइटम शामिल है। आइटम तक पहुंचने के लिए, आपको परिणाम पर लूप करना होगा:

Kotlin+KTX

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (postSnapshot in dataSnapshot.children) {
            // TODO: handle the post
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
        // ...
    }
})

Java

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
});

परिणामों की संख्या सीमित करें

आप किसी दिए गए कॉलबैक के लिए सिंक किए जाने वाले बच्चों की अधिकतम संख्या निर्धारित करने के लिए limitToFirst() और limitToLast() तरीकों का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप 100 की सीमा निर्धारित करने के लिए limitToFirst() उपयोग करते हैं, तो आपको प्रारंभ में केवल 100 onChildAdded() कॉलबैक प्राप्त होते हैं। यदि आपके फायरबेस डेटाबेस में 100 से कम आइटम संग्रहीत हैं, तो प्रत्येक आइटम के लिए onChildAdded() कॉलबैक सक्रिय हो जाता है।

जैसे-जैसे आइटम बदलते हैं, आपको क्वेरी में प्रवेश करने वाले आइटम के लिए onChildAdded() कॉलबैक प्राप्त होते हैं और इससे बाहर निकलने वाले आइटम के लिए onChildRemoved() कॉलबैक प्राप्त होते हैं ताकि कुल संख्या 100 पर बनी रहे।

निम्नलिखित उदाहरण दर्शाता है कि कैसे उदाहरण ब्लॉगिंग ऐप सभी उपयोगकर्ताओं द्वारा 100 सबसे हालिया पोस्ट की सूची पुनर्प्राप्त करने के लिए एक क्वेरी को परिभाषित करता है:

Kotlin+KTX

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys.
databaseReference.child("posts").limitToFirst(100)

Java

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
Query recentPostsQuery = databaseReference.child("posts")
        .limitToFirst(100);

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

कुंजी या मान के आधार पर फ़िल्टर करें

आप प्रश्नों के लिए मनमाना प्रारंभ, समाप्ति और समतुल्य बिंदु चुनने के लिए startAt() startAfter() , endAt() , endBefore() , एंडबिफोर() और equalTo() का उपयोग कर सकते हैं। यह डेटा को पेजिनेट करने या बच्चों के साथ उन वस्तुओं को खोजने के लिए उपयोगी हो सकता है जिनका एक विशिष्ट मूल्य है।

क्वेरी डेटा का ऑर्डर कैसे दिया जाता है

यह अनुभाग बताता है कि Query क्लास में प्रत्येक ऑर्डर-बाय विधि द्वारा डेटा को कैसे क्रमबद्ध किया जाता है।

orderByChild

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

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

orderByKey

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

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

orderByValue

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

अगले कदम