क्वेरी एक्ज़ीक्यूट करने का रेफ़रंस

इस पेज पर, क्वेरी के बारे में जानकारी देने वाली सुविधा की मदद से क्वेरी को एक्ज़ीक्यूट करने के बाद मिलने वाले आउटपुट के बारे में बताया गया है. क्वेरी एक्सप्लेन की मदद से क्वेरी को लागू करने का तरीका जानने के लिए, क्वेरी एक्सप्लेन की मदद से क्वेरी को लागू करने का तरीका लेख पढ़ें.

सामान्य कॉन्सेप्ट

एग्ज़ीक्यूशन ट्री में, इन सामान्य सिद्धांतों और शब्दों का इस्तेमाल किया जाता है.

लाइनें और रिकॉर्ड

लाइन और रिकॉर्ड शब्दों का इस्तेमाल, आम तौर पर किसी दस्तावेज़ या इंडेक्स के रिकॉर्ड के लिए किया जाता है.

वैरिएबल

$ एक वैरिएबल को दिखाता है, जिसे एक्ज़ीक्यूशन ट्री में बनाया गया है या रेफ़रंस के तौर पर इस्तेमाल किया गया है. उदाहरण के लिए: $foo_1. आम तौर पर, इन वैरिएबल का इस्तेमाल किसी दस्तावेज़ के कॉन्टेंट या क्वेरी के लागू होने के दौरान, आकलन किए गए एक्सप्रेशन की वैल्यू को रेफ़र करने के लिए किया जाता है.

एक्ज़ीक्यूशन नोड में ये इंटरनल वैरिएबल दिख सकते हैं:

  • $__key__ - कुंजी, किसी दस्तावेज़ के लिए इंटरनल आइडेंटिफ़ायर होती है. यह एक यूनीक आइडेंटिफ़ायर है. इसमें प्रोजेक्ट, डेटाबेस, और दस्तावेज़ का पूरा पाथ शामिल होता है.
  • $__id__ - आईडी, किसी कलेक्शन में मौजूद दस्तावेज़ का यूनीक आइडेंटिफ़ायर होता है. यह किसी एक कलेक्शन में यूनीक होता है.
  • $rid - लाइन आईडी, स्टोरेज में मौजूद किसी दस्तावेज़ का इंटरनल आइडेंटिफ़ायर होता है. यह किसी एक कलेक्शन में यूनीक होता है.

एक उदाहरण देखें, जिसमें दस्तावेज़ __key__ से __id__ का हिसाब लगाने के लिए, Compute नोड का इस्तेमाल किया गया है:

Compute
    |  $__id__1: _id($__key__)
    |  records returned: 1

सीमाएं और रेंज

कुछ स्कैन नोड, स्कैन की गई वैल्यू की रेंज के बारे में बताने के लिए, constraints और ranges एट्रिब्यूट का इस्तेमाल करते हैं. ये एट्रिब्यूट, रेंज ट्री फ़ॉर्मैट का इस्तेमाल करते हैं. इसमें वैल्यू की एक सूची होती है. ये वैल्यू, कुंजियों की क्रम वाली सूची से जुड़ी होती हैं. ये कुंजियां, इंडेक्स की परिभाषा में दिखती हैं. उदाहरण के लिए, ट्री में दिखने वाली पहली रेंज, यहां (1..5], कुंजियों की क्रम वाली सूची में पहली कुंजी, यहां a, की सीमाओं से मेल खाती है:

| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
               |----(1..5]
                    |----[1L]

इंडेंटेशन का हर लेवल, सूची में अगली कुंजी पर लागू होने वाली पाबंदी को दिखाता है. स्क्वेयर ब्रैकेट, इन्क्लूसिव रेंज को दिखाते हैं. वहीं, राउंड ब्रैकेट, एक्सक्लूसिव रेंज को दिखाते हैं. इस मामले में, पाबंदी का मतलब 1 < "a" <= 5 और "b" = 1 है.

a के लिए कई ब्रांच वाले इस उदाहरण में, शर्त 1 < a <= 5 OR a = 10 से मेल खाती है:

| constraints: /
               |----(1L, 5L]
               |----[10L]

मुख्य वैरिएबल

कुछ स्कैन नोड (जैसे कि SequentialScan) में, index एट्रिब्यूट के हिस्से के तौर पर कुंजियों की सूची और Scan नोड में एक अलग keys एट्रिब्यूट, दोनों होते हैं. Scan नोड में मौजूद keys एट्रिब्यूट, इंडेक्स की परिभाषा में मौजूद हर कुंजी के वैरिएबल नाम को क्रम से दिखाता है. एग्ज़ीक्यूशन ट्री में, स्कैन किए गए फ़ील्ड की रनटाइम वैल्यू को रेफ़र करने के लिए, वैरिएबल का इस्तेमाल किया जा सकता है.

इस उदाहरण में, मौजूदा दस्तावेज़ के लिए user फ़ील्ड की वैल्यू, वैरिएबल $user_1 से मैप होती है. साथ ही, date_placed की वैल्यू, $date_placed_1 से मैप होती है.

index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]

एक्ज़ीक्यूशन नोड

क्वेरी एक्ज़ीक्यूशन ट्री में ये नोड हो सकते हैं.

SeekingScan

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

उदाहरण के लिए, ऐसी क्वेरी जिसमें a मौजूद है और b की वैल्यू 1 है, ["a" ASC, "b" ASC] के इंडेक्स पर काम करती है. इसके लिए, a की हर अलग वैल्यू के लिए, एक अलग और संभावित रूप से क्रम में न होने वाली रेंज को स्कैन करना और उसे दिखाना होगा. यह पूरे TableScan से ज़्यादा बेहतर है, लेकिन ["b" ASC, "a" ASC] के कंपोज़िट इंडेक्स पर एक SequentialScan से कम बेहतर है.

• SeekingScan
| constraints: /
               |----(-∞..+∞)
                    |----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1

SequentialScan

यह स्टोरेज में मौजूद पंक्तियों की स्टैटिक और क्रम से चलने वाली रेंज के स्कैन को दिखाता है. इसे एक ही बार में पढ़ा जा सकता है.

key ordering length से पता चलता है कि कितनी कुंजियों को सुरक्षित रखना है और उन्हें ओरिजनल क्रम में दिखाना है. [k1, k2, k3] के स्कीमा के लिए, कुंजी के क्रम की लंबाई 0 होने का मतलब है कि स्कैन किसी भी क्रम में नतीजे दिखा सकता है. 1 का मतलब है कि k1 के हिसाब से क्रम से लगाया गया है, लेकिन एक जैसी k1 वैल्यू वाली लाइनें किसी भी क्रम में आ सकती हैं. 3 का मतलब है कि दस्तावेज़ों को पूरी तरह से क्रम से लगाकर दिखाया जाता है.

• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1

UniqueScan

यह स्टोरेज में मौजूद पंक्तियों की स्टैटिक और क्रम से चलने वाली रेंज को स्कैन करता है. साथ ही, इन-मेमोरी में मौजूद पंक्तियों की डुप्लीकेट कॉपी हटाता है.

• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
          |----(-∞..+∞)
| records returned: 1
| records scanned: 1

IndexSeek

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

उदाहरण के लिए, ऐसी क्वेरी जिसमें user, $user_id के बराबर है और date_placed, "2025-08-10" के बराबर है. यह क्वेरी, ["user" ASC, "date_placed" ASC] के इंडेक्स पर चल रही है. यह क्वेरी, रनटाइम के दौरान $user_id वैरिएबल की वैल्यू और date_placed पर "2025-08-10" की पाबंदी का इस्तेमाल करेगी, ताकि स्कैन की रेंज को सीमित किया जा सके.

• IndexSeek
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| fields: [$user_1 ASC, $date_placed_1 ASC, $rid ASC]
| key: $key_1
| filter: $eq($user_1, $user_id) AND $eq($date_placed_1, "2025-08-10")
| records returned: 1
| records scanned: 1

लाएं

यह दी गई लाइन के आइडेंटिफ़ायर को प्राइमरी स्टोरेज में मौजूद लाइन के असल कॉन्टेंट से फिर से जोड़ता है. अगर पैरंट नोड (या क्वेरी के आखिरी नतीजे) को दस्तावेज़ों के फ़ील्ड के सबसेट की ज़रूरत है, तो Fetch ज़रूरी है.

• Fetch
|  order: PRESERVE_INPUT_ORDER
|  peak memory usage: 4.00 KiB (4,096 B)
|  properties: *
|  records returned: 1

TableScan

किसी कलेक्शन का पूरा और बिना क्रम वाला स्कैन. इसका इस्तेमाल तब किया जाता है, जब किसी क्वेरी को उससे जुड़े इंडेक्स के बिना चलाया जाता है.

क्रम STABLE या UNDEFINED हो सकता है. इसमें STABLE, डिटरमिनिस्टिक ऑर्डर को दिखाता है.

• TableScan
|  order: STABLE
|  properties: *
|  records returned: 1
|  records scanned: 1
|  source: (default)#/**/collection

लागू करें

यह input की हर लाइन को दोहराकर, डेटा के दो सेट (input और map) को जोड़ता है. साथ ही, हर लाइन के लिए, map साइड से नतीजों को स्कैन करके दिखाता है.

join_type से पता चलता है कि किस तरह का जॉइन इस्तेमाल किया गया है. उदाहरण के लिए, LEFT_OUTER का मतलब है कि input की सभी लाइनें, आउटपुट में कम से कम एक बार शामिल की गई हैं. अगर input पंक्ति को map साइड से कोई नतीजा नहीं मिलता है, तो भी उसे शामिल किया जाएगा. साथ ही, map साइड के कॉलम के लिए null वैल्यू शामिल की जाएंगी.

• Apply
|  join_type: LEFT_OUTER
|
└── • input tree
|     ...
└── • map tree
      ...

HashAggregate

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

• HashAggregate
|  aggregations: [sum($b_1) AS total]
|  groups: [$a_1]
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 0

StreamAggregate

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

• StreamAggregate
|  keys: [foo ASC, bar ASC]
|  properties: Selection { baz }
|  aggregations: [$sum($foo_1) AS baz]

MajorSort

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

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

• MajorSort
|  fields: [a ASC, b DESC]
|  limit: 10
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 1

Concat

यह कई चाइल्ड नोड के नतीजों को जोड़ता है और नतीजे को पैरंट नोड पर दिखाता है. यह नोड, एक से ज़्यादा चाइल्ड नोड में दिखने वाले नतीजों की डुप्लीकेट कॉपी नहीं हटाता. साथ ही, दिखाए गए नतीजों का क्रम तय नहीं होता.

• Concat
├── • Fetch
...
├── • Fetch

कंप्यूट

यह एक्सप्रेशन के सेट का आकलन करता है और नतीजों को वैरिएबल के सेट को असाइन करता है.

• Compute
|  $user_1: user
|  $full_name_1: str_concat($first_name_1, " ", $last_name_1)
|  $address_1: UNSET
|  records returned: 1

फ़िल्टर

यह फ़ंक्शन, चुनिंदा पंक्तियां दिखाता है. हालांकि, ऐसा सिर्फ़ तब होता है, जब वे दिए गए एक्सप्रेशन से मैच करती हों.

• Filter
|  expression: $eq(foo, "bar")
|  records returned: 1

RecordCount

यह चाइल्ड नोड से जनरेट हुई लाइनों की संख्या की गिनती करता है. साथ ही, मौजूदा संख्या को count एट्रिब्यूट में बताए गए वैरिएबल में दिखाता है.

• RecordCount
|  count: $row_number_1
|  records returned: 1

वैल्यू

यह लिटरल वैल्यू का एक क्रम जनरेट करता है, ताकि उन पर काम किया जा सके. इसका इस्तेमाल मुख्य रूप से तब किया जाता है, जब किसी क्वेरी के इनपुट के तौर पर दस्तावेज़ों की एक सेट सूची दी जाती है.

• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]

Unnest

चाइल्ड नोड से जनरेट की गई वैल्यू को अननेस्ट करता है.

• Unnest
|  expression: foo AS unnested_foo

सीमा

यह पैरंट नोड को दिखाई जाने वाली पंक्तियों की संख्या को सीमित करता है.

• Limit
|  limit: 10
|  records returned: 1

ऑफ़सेट

यह चाइल्ड नोड से जनरेट की गई लाइनों की तय संख्या को छोड़ देता है.

• Offset
|  offset: 10
|  records returned: 1