इस ट्यूटोरियल में, Bazel प्रोजेक्ट का इस्तेमाल करके, अपने कोड में डिपेंडेंसी ट्रैक करने के लिए Bazel का इस्तेमाल करने का तरीका बताया गया है.
भाषा और --output फ़्लैग की जानकारी के लिए, Bazel क्वेरी रेफ़रंस और Bazel cquery रेफ़रंस के मैन्युअल देखें. कमांड लाइन पर bazel help query या bazel help cquery टाइप करके, अपने आईडीई में मदद पाएं.
मकसद
इस गाइड में, कुछ बुनियादी क्वेरी के बारे में बताया गया है. इनका इस्तेमाल करके, अपने प्रोजेक्ट की फ़ाइल डिपेंडेंसी के बारे में ज़्यादा जाना जा सकता है. यह गाइड, Bazel के नए डेवलपर के लिए है. इसमें Bazel और BUILD फ़ाइलों के काम करने के तरीके के बारे में बुनियादी जानकारी दी गई है.
ज़रूरी शर्तें
अगर आपने Bazel को अब तक इंस्टॉल नहीं किया है, तो सबसे पहले इसे इंस्टॉल करें. इस ट्यूटोरियल में, सोर्स कंट्रोल के लिए Git का इस्तेमाल किया गया है. इसलिए, बेहतर नतीजों के लिए Git को भी इंस्टॉल करें.
डिपेंडेंसी ग्राफ़ को विज़ुअलाइज़ करने के लिए, Graphviz नाम के टूल का इस्तेमाल किया जाता है. इसे डाउनलोड करके, साथ-साथ काम किया जा सकता है.
सैंपल प्रोजेक्ट पाना
इसके बाद, अपनी पसंद के कमांड-लाइन टूल में यह निर्देश डालकर, Bazel के उदाहरणों के डेटाबेस से सैंपल ऐप्लिकेशन वापस पाएं:
git clone https://github.com/bazelbuild/examples.gitइस ट्यूटोरियल के लिए सैंपल प्रोजेक्ट, examples/query-quickstart डायरेक्ट्री में है.
शुरू करना
Bazel क्वेरी क्या होती हैं?
क्वेरी की मदद से, Bazel के कोडबेस के बारे में जाना जा सकता है. इसके लिए, BUILD फ़ाइलों के बीच के संबंधों का विश्लेषण किया जाता है और काम की जानकारी के लिए, नतीजों के तौर पर मिले आउटपुट की जांच की जाती है. इस गाइड में, क्वेरी के कुछ बुनियादी फ़ंक्शन की झलक दिखाई गई है. हालांकि, ज़्यादा विकल्पों के लिए, क्वेरी गाइड देखें. क्वेरी की मदद से, बड़े प्रोजेक्ट में डिपेंडेंसी के बारे में जाना जा सकता है. इसके लिए, BUILD फ़ाइलों में मैन्युअल तरीके से नेविगेट करने की ज़रूरत नहीं होती.
क्वेरी चलाने के लिए, कमांड लाइन टर्मिनल खोलें और यह निर्देश डालें:
bazel query 'query_function'स्थिति
मान लें कि आपको Cafe Bazel और उसके शेफ़ के बीच के संबंध के बारे में जानना है. यह कैफ़े सिर्फ़ पिज़्ज़ा और मैकरोनी ऐंड चीज़ बेचता है. यहां देखें कि प्रोजेक्ट का स्ट्रक्चर कैसा है:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazel
इस ट्यूटोरियल में, जब तक कोई निर्देश न दिया जाए, तब तक अपनी ज़रूरत की जानकारी पाने के लिए BUILD फ़ाइलों में न देखें. इसके बजाय, सिर्फ़ क्वेरी फ़ंक्शन का इस्तेमाल करें.
किसी प्रोजेक्ट में अलग-अलग पैकेज होते हैं, जिनसे मिलकर एक कैफ़े बनता है. इन्हें इन कैटगरी में बांटा गया है: restaurant, ingredients, dishes, customers, और reviews. इन पैकेज में मौजूद नियमों से, कैफ़े के अलग-अलग कॉम्पोनेंट तय होते हैं. इनमें अलग-अलग टैग और डिपेंडेंसी होती हैं.
बिल्ड चलाना
इस प्रोजेक्ट में Runner.java के अंदर एक मुख्य तरीका शामिल है. इसे एक्ज़ीक्यूट करके, कैफ़े का मेन्यू प्रिंट किया जा सकता है. Bazel का इस्तेमाल करके, bazel build निर्देश से प्रोजेक्ट बनाएं. साथ ही, यह बताने के लिए : का इस्तेमाल करें कि टारगेट का नाम runner है. टारगेट को रेफ़र करने का तरीका जानने के लिए,
टारगेट के नाम देखें.
इस प्रोजेक्ट को बनाने के लिए, यह निर्देश किसी टर्मिनल में चिपकाएं:
bazel build :runnerअगर बिल्ड पूरा हो जाता है, तो आपका आउटपुट कुछ ऐसा दिखेगा.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actions
बिल्ड पूरा होने के बाद, इस निर्देश को चिपकाकर ऐप्लिकेशन चलाएं:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------
इससे आपको मेन्यू में शामिल आइटम की सूची और उनकी संक्षिप्त जानकारी मिलती है.
टारगेट एक्सप्लोर करना
प्रोजेक्ट में, सामग्री और डिश को उनके पैकेज में शामिल किया गया है. किसी पैकेज के नियमों को देखने के लिए, क्वेरी का इस्तेमाल करने के लिए, bazel query package/… निर्देश चलाएं
इस मामले में, इस कैफ़े में मौजूद सामग्री और डिश को देखने के लिए, यह निर्देश चलाएं:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...अगर सामग्री के पैकेज के टारगेट के लिए क्वेरी की जाती है, तो आउटपुट ऐसा दिखना चाहिए:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
डिपेंडेंसी ढूंढना
आपका रनर, किन टारगेट पर निर्भर करता है?
मान लें कि आपको फ़ाइल सिस्टम में जाए बिना, अपने प्रोजेक्ट के स्ट्रक्चर के बारे में ज़्यादा जानकारी चाहिए. हालांकि, बड़े प्रोजेक्ट के लिए यह मुमकिन नहीं है. Cafe Bazel किन नियमों का इस्तेमाल करता है?
अगर इस उदाहरण की तरह, आपके रनर का टारगेट runner है, तो यह निर्देश चलाकर टारगेट की डिपेंडेंसी के बारे में जानें:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
ज़्यादातर मामलों में, किसी खास टारगेट की अलग-अलग आउटपुट डिपेंडेंसी देखने के लिए, क्वेरी फ़ंक्शन deps() का इस्तेमाल करें.
डिपेंडेंसी ग्राफ़ को विज़ुअलाइज़ करना (ज़रूरी नहीं)
इस सेक्शन में, किसी खास क्वेरी के लिए डिपेंडेंसी पाथ को विज़ुअलाइज़ करने का तरीका बताया गया है. Graphviz की मदद से, पाथ को फ़्लैट सूची के बजाय, डायरेक्टेड एसाइक्लिक ग्राफ़ इमेज के तौर पर देखा जा सकता है. Bazel क्वेरी ग्राफ़ के डिसप्ले में बदलाव करने के लिए, --output कमांड लाइन के अलग-अलग विकल्पों का इस्तेमाल किया जा सकता है. विकल्पों के लिए, आउटपुट फ़ॉर्मैट देखें.
सबसे पहले, अपनी पसंद की क्वेरी चलाएं. इसके बाद, टूल की ज़्यादा डिपेंडेंसी हटाने के लिए, --noimplicit_deps फ़्लैग जोड़ें. इसके बाद, क्वेरी के साथ आउटपुट फ़्लैग जोड़ें और ग्राफ़ को graph.in नाम की फ़ाइल में सेव करें. इससे ग्राफ़ का टेक्स्ट वर्शन बन जाएगा.
टारगेट :runner की सभी डिपेंडेंसी खोजने और आउटपुट को ग्राफ़ के तौर पर फ़ॉर्मैट करने के लिए:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inइससे graph.in नाम की एक फ़ाइल बनती है. यह बिल्ड ग्राफ़ का टेक्स्ट वर्शन होता है. Graphviz, dot टूल का इस्तेमाल करके, png बनाता है. यह टूल, टेक्स्ट को विज़ुअलाइज़ेशन में बदलता है:
dot -Tpng < graph.in > graph.pnggraph.png खोलने पर, आपको कुछ ऐसा दिखेगा. इस गाइड में, पाथ की ज़रूरी जानकारी को साफ़ तौर पर दिखाने के लिए, नीचे दिए गए ग्राफ़ को आसान बनाया गया है.

इससे, इस गाइड में क्वेरी के अलग-अलग फ़ंक्शन के आउटपुट देखने में मदद मिलती है.
रिवर्स डिपेंडेंसी ढूंढना
अगर आपके पास कोई ऐसा टारगेट है जिसका विश्लेषण करना है, तो क्वेरी का इस्तेमाल करके यह देखा जा सकता है कि कौनसे टारगेट, किसी नियम पर निर्भर करते हैं. इसे “रिवर्स डिपेंडेंसी” कहा जाता है. rdeps() का इस्तेमाल तब किया जा सकता है, जब आपको किसी ऐसे कोडबेस में कोई फ़ाइल में बदलाव करना हो जिसके बारे में आपको जानकारी न हो. इससे, अनजाने में उन अन्य फ़ाइलों को टूटने से बचाया जा सकता है जो इस पर निर्भर थीं.
उदाहरण के लिए, आपको cheese सामग्री में कुछ बदलाव करने हैं. Cafe Bazel के लिए कोई समस्या न हो, इसके लिए आपको यह देखना होगा कि कौनसी डिश cheese पर निर्भर करती हैं.
यह देखने के लिए कि कौनसे टारगेट, किसी खास टारगेट/पैकेज पर निर्भर करते हैं, rdeps(universe_scope, target) का इस्तेमाल किया जा सकता है. rdeps() क्वेरी फ़ंक्शन में कम से कम दो तर्क होते हैं: एक universe_scope — काम की डायरेक्ट्री — और एक target. Bazel, दिए गए universe_scope में टारगेट की रिवर्स डिपेंडेंसी खोजता है. rdeps() ऑपरेटर, तीसरा तर्क भी स्वीकार करता है. यह एक इंटिजर लिटरल होता है, जो खोज की गहराई की ऊपरी सीमा तय करता है.
पूरे प्रोजेक्ट ‘//…’ के स्कोप में, टारगेट cheese की रिवर्स डिपेंडेंसी खोजने के लिए, यह निर्देश चलाएं:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"
//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
क्वेरी के नतीजे से पता चलता है कि पिज़्ज़ा और मैकरोनी ऐंड चीज़, दोनों में चीज़ का इस्तेमाल किया जाता है. यह तो कमाल की बात है!
टैग के आधार पर टारगेट ढूंढना
Bazel कैफ़े में दो ग्राहक आते हैं: आमिर और जेनी. उनके नाम के अलावा, उनके बारे में कोई जानकारी नहीं है. अच्छी बात यह है कि उनके ऑर्डर, 'customers' BUILD फ़ाइल में टैग किए गए हैं. इस टैग को कैसे ऐक्सेस किया जा सकता है?
डेवलपर, Bazel के टारगेट को अलग-अलग आइडेंटिफ़ायर से टैग कर सकते हैं. ऐसा अक्सर टेस्ट के मकसद से किया जाता है. उदाहरण के लिए, टेस्ट पर मौजूद टैग, आपके डीबग और रिलीज़ प्रोसेस में टेस्ट की भूमिका को एनोटेट कर सकते हैं. खास तौर पर, C++ और Python टेस्ट के लिए, जिनमें रनटाइम एनोटेशन की कोई सुविधा नहीं होती. टैग और साइज़ एलिमेंट का इस्तेमाल करके, कोडबेस की चेक-इन नीति के आधार पर टेस्ट के सुइट को इकट्ठा करने में मदद मिलती है.
इस उदाहरण में, मेन्यू आइटम को दिखाने के लिए, टैग pizza या macAndCheese में से कोई एक है. यह निर्देश, किसी खास पैकेज में उन टारगेट के लिए क्वेरी करता है जिनमें आपके आइडेंटिफ़ायर से मेल खाने वाले टैग होते हैं.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'
यह क्वेरी, 'customers' पैकेज में मौजूद उन सभी टारगेट को दिखाती है जिनमें "pizza" का टैग है.
अपनी जानकारी की जांच करें
यह क्वेरी इस्तेमाल करके जानें कि जेनी क्या ऑर्डर करना चाहती है.
जवाब
मैकरोनी ऐंड चीज़
नई डिपेंडेंसी जोड़ना
Cafe Bazel ने अपने मेन्यू में एक नया आइटम जोड़ा है. अब ग्राहक स्मूदी ऑर्डर कर सकते हैं! इस स्मूदी में Strawberry और Banana सामग्री का इस्तेमाल किया गया है.
सबसे पहले, स्मूदी में इस्तेमाल की जाने वाली सामग्री जोड़ें: Strawberry.java और Banana.java. खाली Java क्लास जोड़ें.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}
src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}
इसके बाद, Smoothie.java को सही डायरेक्ट्री में जोड़ें: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}
आखिर में, इन फ़ाइलों को सही BUILD फ़ाइलों में नियमों के तौर पर जोड़ें. हर नई सामग्री के लिए, एक नई Java लाइब्रेरी बनाएं. इसमें उसका नाम, सार्वजनिक तौर पर दिखने की सेटिंग, और नई बनाई गई 'src' फ़ाइल शामिल करें. अपडेट की गई BUILD फ़ाइल ऐसी दिखनी चाहिए:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)
डिश के लिए BUILD फ़ाइल में, आपको Smoothie के लिए एक नया नियम जोड़ना है. ऐसा करने से, Smoothie के लिए बनाई गई Java फ़ाइल, 'src' फ़ाइल के तौर पर शामिल हो जाती है. साथ ही, स्मूदी में इस्तेमाल की गई हर सामग्री के लिए बनाए गए नए नियम भी शामिल हो जाते हैं.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)
आखिर में, आपको शेफ़ की BUILD फ़ाइल में स्मूदी को डिपेंडेंसी के तौर पर शामिल करना है.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)
cafe को फिर से बनाकर, पुष्टि करें कि कोई गड़बड़ी नहीं है. अगर बिल्ड पूरा हो जाता है, तो बधाई हो! आपने 'कैफ़े' के लिए एक नई डिपेंडेंसी जोड़ी है. अगर ऐसा नहीं होता है, तो स्पेलिंग की गड़बड़ियां और पैकेज के नामकरण की जांच करें. BUILD फ़ाइलें लिखने के बारे में ज़्यादा जानने के लिए, BUILD स्टाइल गाइड देखें.
अब Smoothie को शामिल करके, नए डिपेंडेंसी ग्राफ़ को विज़ुअलाइज़ करें. इससे इसकी तुलना पिछले ग्राफ़ से की जा सकेगी. साफ़ तौर पर दिखाने के लिए, ग्राफ़ के इनपुट को graph2.in और graph2.png नाम दें.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pnggraph2.png को देखकर, यह पता चलता है कि Smoothie की अन्य डिश के साथ कोई शेयर की गई डिपेंडेंसी नहीं है. हालांकि, यह एक और टारगेट है जिस पर Chef निर्भर करता है.
somepath() और allpaths()
अगर आपको यह क्वेरी करनी है कि कोई पैकेज, किसी दूसरे पैकेज पर क्यों निर्भर करता है, तो क्या होगा? दोनों के बीच डिपेंडेंसी पाथ दिखाने से, जवाब मिल जाता है.
डिपेंडेंसी पाथ ढूंढने में, दो फ़ंक्शन आपकी मदद कर सकते हैं: somepath() और allpaths(). शुरुआती टारगेट S और एंड पॉइंट E दिए जाने पर, somepath(S,E) का इस्तेमाल करके, S और E के बीच का पाथ ढूंढें.
'शेफ़' और 'चीज़' टारगेट के बीच के संबंधों को देखकर, इन दोनों फ़ंक्शन के बीच के अंतर को एक्सप्लोर करें. एक टारगेट से दूसरे टारगेट तक पहुंचने के लिए, अलग-अलग पाथ हो सकते हैं:
- शेफ़ → मैकरोनी ऐंड चीज़ → चीज़
- शेफ़ → पिज़्ज़ा → चीज़
somepath() आपको दो विकल्पों में से एक पाथ देता है. वहीं, 'allpaths()' हर संभावित पाथ का आउटपुट देता है.
Cafe Bazel को उदाहरण के तौर पर इस्तेमाल करके, यह निर्देश चलाएं:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheese
आउटपुट, Cafe → शेफ़ → मैकरोनी ऐंड चीज़ → चीज़ के पहले पाथ को फ़ॉलो करता है. अगर इसके बजाय allpaths() का इस्तेमाल किया जाता है, तो आपको यह आउटपुट मिलता है:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef

allpaths() का आउटपुट पढ़ना थोड़ा मुश्किल होता है, क्योंकि यह डिपेंडेंसी की फ़्लैट सूची होती है. Graphviz का इस्तेमाल करके, इस ग्राफ़ को विज़ुअलाइज़ करने से, संबंध को समझना आसान हो जाता है.
अपनी जानकारी की जांच करें
Cafe Bazel के एक ग्राहक ने रेस्टोरेंट की पहली समीक्षा दी है! हालांकि, समीक्षा में कुछ जानकारी मौजूद नहीं है. जैसे, समीक्षा करने वाले की पहचान और वह किस डिश के बारे में बता रहा है. अच्छी बात यह है कि Bazel की मदद से, इस जानकारी को ऐक्सेस किया जा सकता है. reviews पैकेज में एक ऐसा प्रोग्राम शामिल है जो किसी अनजान ग्राहक की समीक्षा प्रिंट करता है. इसे बनाने और चलाने के लिए, यह निर्देश डालें:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewसिर्फ़ Bazel क्वेरी का इस्तेमाल करके, यह पता लगाने की कोशिश करें कि समीक्षा किसने लिखी है और वह किस डिश के बारे में बता रहा था.
संकेत
काम की जानकारी के लिए, टैग और डिपेंडेंसी देखें.
जवाब
इस समीक्षा में पिज़्ज़ा के बारे में बताया गया था और समीक्षा करने वाला आमिर था. अगर आप यह देखते हैं कि इस नियम में किन डिपेंडेंसी का इस्तेमाल किया गया है, तो
bazel query --noimplicit\_deps 'deps(//src/main/java/com/example/reviews:review)'
का इस्तेमाल करें. इस निर्देश के नतीजे से पता चलता है कि समीक्षा करने वाला आमिर है!
इसके बाद, जब आपको पता चल जाता है कि समीक्षा करने वाला आमिर है, तो क्वेरी फ़ंक्शन का इस्तेमाल करके यह देखा जा सकता है कि `BUILD` फ़ाइल में आमिर के पास कौनसे टैग हैं. इससे यह पता चलता है कि वहां कौनसी डिश है.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)' निर्देश के आउटपुट से पता चलता है कि आमिर, पिज़्ज़ा ऑर्डर करने वाला इकलौता ग्राहक है और वही समीक्षा करने वाला है. इससे हमें जवाब मिल जाता है.
रैप अप
बधाई हो! अब आपने कई बुनियादी क्वेरी चला ली हैं. इन्हें अपने प्रोजेक्ट पर भी आज़माया जा सकता है. क्वेरी लैंग्वेज सिंटैक्स के बारे में ज़्यादा जानने के लिए, क्वेरी रेफ़रंस पेज देखें. क्या आपको और भी बेहतर क्वेरी चाहिए? क्वेरी गाइड में, इस गाइड में शामिल किए गए उदाहरणों के मुकाबले, ज़्यादा उदाहरणों की पूरी सूची दिखाई गई है.
