क्वेरी क्विकस्टार्ट

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

भाषा और --output फ़्लैग की जानकारी के लिए, Bazel क्वेरी के बारे में जानकारी और Bazel cquery रेफ़रंस मैन्युअल देखें. कमांड लाइन पर bazel help query या bazel help cquery टाइप करके, अपने आईडीई में मदद पाएं.

उद्देश्य

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

ज़रूरी शर्तें

अगर आपने पहले से Bazel इंस्टॉल नहीं किया है, तो उसे इंस्टॉल करें. यह ट्यूटोरियल स्रोत नियंत्रण के लिए Git का इस्तेमाल करता है, इसलिए सबसे अच्छे नतीजों के लिए, Git भी इंस्टॉल करें.

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

सैंपल प्रोजेक्ट पाएं

इसके बाद, अपनी पसंद के कमांड-लाइन टूल में Bazel's Example डेटा स्टोर करने की जगह से ऐप्लिकेशन का नमूना पाएं:

git clone https://github.com/bazelbuild/examples.git

इस ट्यूटोरियल का सैंपल प्रोजेक्ट, examples/query-quickstart डायरेक्ट्री में मौजूद है.

शुरू करना

Bazel क्वेरी क्या हैं?

क्वेरी की मदद से, BUILD फ़ाइलों के बीच के संबंधों का विश्लेषण करके और नतीजे के तौर पर काम की जानकारी पाने के लिए, बेज़ल कोडबेस के बारे में जाना जा सकता है. यह गाइड कुछ बुनियादी क्वेरी फ़ंक्शन की झलक दिखाती है, लेकिन ज़्यादा विकल्पों के लिए क्वेरी गाइड देखें. क्वेरी से, आपको BUILD फ़ाइलों पर मैन्युअल तरीके से नेविगेट किए बिना, बड़े पैमाने पर प्रोजेक्ट में डिपेंडेंसी के बारे में जानकारी मिलती है.

कोई क्वेरी चलाने के लिए, अपना कमांड लाइन टर्मिनल खोलें और Enter दबाएं:

bazel query 'query_function'

स्थिति

एक ऐसी स्थिति के बारे में सोचें जब कैफ़े बाज़ल और उसके शेफ़ के बीच का रिश्ता पता चलता है. यह कैफ़े खास तौर पर पिज़्ज़ा और मैक और चीज़ बेचता है. इस प्रोजेक्ट को बनाने का तरीका जानें:

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
└── WORKSPACE

इस ट्यूटोरियल में, अपनी ज़रूरत के हिसाब से जानकारी ढूंढने के लिए, 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

डिपेंडेंसी ढूंढना

दौड़ने के लिए, रनर किस टारगेट पर भरोसा करता है?

मान लें कि आप फ़ाइल सिस्टम में पेश किए बिना (जो शायद बड़े प्रोजेक्ट के लिए चालू न हो पाए) अपने प्रोजेक्ट के स्ट्रक्चर की गहराई से जानना चाहते हैं. कैफ़े बेज़ल किन नियमों का इस्तेमाल करता है?

अगर इस उदाहरण में, आपके रनर के लिए टारगेट 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() का इस्तेमाल करें.

डिपेंडेंसी ग्राफ़ विज़ुअलाइज़ करना (ज़रूरी नहीं)

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

अपनी पसंद की क्वेरी चलाने से शुरुआत करें और टूल डिपेंडेंसी हटाने के लिए, --noimplicit_deps फ़्लैग जोड़ें. इसके बाद, आउटपुट फ़्लैग वाली क्वेरी को फ़ॉलो करें और ग्राफ़ को टेक्स्ट फ़ाइल बनाने के लिए, graph.in नाम की फ़ाइल में सेव करें.

टारगेट :runner की सभी डिपेंडेंसी खोजने के लिए और आउटपुट को ग्राफ़ के तौर पर फ़ॉर्मैट करने के लिए:

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.in

इससे graph.in नाम की एक फ़ाइल बनती है, जिसमें बिल्ड ग्राफ़ होता है. ग्राफ़विज़ png बनाने के लिए dot टूल का इस्तेमाल करता है जो टेक्स्ट को विज़ुअलाइज़ेशन में प्रोसेस करता है:

dot -Tpng < graph.in > graph.png

graph.png को खोलने पर, आपको कुछ ऐसा दिखेगा. नीचे दिए गए ग्राफ़ को आसान बनाया गया है, ताकि इस गाइड में ज़रूरी पाथ की जानकारी को साफ़ तौर पर बताया जा सके.

कैफ़े से शेफ़ और पकवान तक के रिश्ते को दिखाने वाला डायग्राम: पिज़्ज़ा और मैक और चीज़ जो अलग-अलग सामग्री में गिरते हैं: चीज़, टमाटर, आटा, और मैकरोनी.

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

रिवर्स डिपेंडेंसी ढूंढना

इसके बजाय, अगर आपके पास कोई टारगेट है, तो आपको यह विश्लेषण करना होगा कि दूसरे टारगेट इसका इस्तेमाल कैसे करते हैं. किसी क्वेरी का इस्तेमाल करके, यह पता लगाया जा सकता है कि कौनसे टारगेट किसी खास नियम पर निर्भर हैं. इसे “रिवर्स डिपेंडेंसी” कहा जाता है. rdeps() का इस्तेमाल करने से, कोडबेस की उस फ़ाइल में बदलाव करने में मदद मिल सकती है जिसके बारे में आपको पता नहीं है. साथ ही, यह आपको उस फ़ाइल पर अनजान से दूसरी फ़ाइलों को तोड़ने से भी रोक सकता है.

उदाहरण के लिए, आपको सामग्री cheese में कुछ बदलाव करना है. कैफ़े बेज़ल की वजह से होने वाली समस्याओं से बचने के लिए, आपको देखना होगा कि cheese पर कौनसे पकवान निर्भर हैं.

यह देखने के लिए कि कौनसे टारगेट किसी खास टारगेट/पैकेज पर निर्भर हैं, rdeps(universe_scope, target) का इस्तेमाल किया जा सकता है. rdeps() क्वेरी फ़ंक्शन को कम से कम दो तर्क की ज़रूरत होती है: universe_scope — संबंधित डायरेक्ट्री — और target. बेज़ल ने 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

क्वेरी रिटर्न से पता चलता है कि पिज़्ज़ा, पिज़्ज़ा और macAndCheise दोनों पर निर्भर है. कितना बढ़िया है!

टैग के आधार पर टारगेट खोजना

बेज़ल कैफ़े: आमिर और जेनी के पास दो ग्राहक गए. उनके नाम के अलावा, उनके बारे में कुछ और नहीं पता होता है. अच्छी बात यह है कि उनके ऑर्डर, 'ग्राहक' BUILD फ़ाइल में टैग किए गए हैं. इस टैग को कैसे ऐक्सेस किया जा सकता है?

डेवलपर, बेज़ल टारगेट को अलग-अलग आइडेंटिफ़ायर के साथ टैग कर सकते हैं. आम तौर पर, ऐसा जांच के मकसद से किया जाता है. उदाहरण के लिए, जांच पर मौजूद टैग आपकी डीबग और रिलीज़ प्रोसेस में जांच की भूमिका के बारे में बता सकते हैं. खास तौर पर, C++ और Python जांचों के लिए, जिनमें रनटाइम के एनोटेशन की सुविधा नहीं होती. टैग और साइज़ एलिमेंट का इस्तेमाल करने पर, कोडबेस की चेक-इन से जुड़ी नीति के आधार पर, टेस्ट के सुइट को इकट्ठा किया जा सकता है.

इस उदाहरण में, मेन्यू आइटम को दिखाने के लिए टैग या तो pizza हैं या macAndCheese हैं. यह निर्देश उन टारगेट के लिए क्वेरी करता है जिनके टैग किसी खास पैकेज में आपके आइडेंटिफ़ायर से मेल खाते हैं.

bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'

यह क्वेरी, 'ग्राहक' पैकेज में मौजूद उन सभी टारगेट की जानकारी देती है जिनमें "पिज़्ज़ा" टैग है.

खुद को आज़माकर देखें

इस क्वेरी का इस्तेमाल करके जानें कि जेनी क्या ऑर्डर करना चाहती है.

जवाब

मैक और चीज़

नई डिपेंडेंसी जोड़ना

कैफ़े बेज़ल ने अपना मेन्यू बढ़ाया है - ग्राहक अब स्मूदी ऑर्डर कर सकते हैं! इस खास स्मूदी में 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",
    ],
)

आखिर में, आपको Chef की 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 फ़ाइलें लिखने के बारे में ज़्यादा जानकारी के लिए बिल्ड स्टाइल गाइड देखें.

अब, पिछले डिपेंडेंसी के साथ तुलना करने के लिए, Smoothie के साथ नया डिपेंडेंसी ग्राफ़ देखें. दूसरे शब्दों में, ग्राफ़ इनपुट को graph2.in और graph2.png के रूप में नाम दें.

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.in
dot -Tpng < graph2.in > graph2.png

पहले वाले की तरह ही इस ग्राफ़िक को छोड़कर, अब बावर्ची के साथ स्मूदी करके लहजे में आवाज़ आती है, जो केले और स्ट्रॉबेरी तक ले जाती है

graph2.png पर नज़र डालकर देखा जा सकता है कि Smoothie, दूसरे डिश के साथ शेयर की गई डिपेंडेंसी नहीं है. हालांकि, यह सिर्फ़ Chef पर निर्भर करता है.

somepath() और allpaths()

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

डिपेंडेंसी पाथ खोजने में, दो फ़ंक्शन आपकी मदद कर सकते हैं: somepath() और allpaths(). शुरुआती टारगेट S और एंड पॉइंट E को देखते हुए, somepath(S,E) का इस्तेमाल करके S और E के बीच का पाथ ढूंढें.

'चीफ़' और 'चीज़' टारगेट के बीच के संबंध को देखकर, इन दोनों फ़ंक्शन के बीच के अंतरों के बारे में जानें. एक टारगेट से दूसरे टारगेट तक पहुंचने के कई तरीके हैं:

  • बावर्ची → MacAndCheees → चीज़
  • शेफ़ → पिज़्ज़ा → चीज़

somepath() से आपको दो विकल्पों में से एक पाथ मिलता है, जबकि 'allpaths()' से हर संभावित पाथ का पता चलता है.

उदाहरण के लिए कैफ़े बेज़ल का इस्तेमाल करते हुए, ये चलाएं:

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

नतीजा, कैफ़े → शेफ़ → मैकएंडशेज़ → चीज़ का पहला पाथ फ़ॉलो करता है. 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() के आउटपुट को पढ़ना थोड़ा मुश्किल है, क्योंकि यह डिपेंडेंसी की चपटी सूची है. ग्राफ़विज़ का इस्तेमाल करके इस ग्राफ़ को विज़ुअलाइज़ करने से, संबंधों को समझने में आसानी होती है.

खुद को आज़माकर देखें

कैफ़े बेज़ल के एक ग्राहक ने रेस्टोरेंट की पहली समीक्षा की! माफ़ करें, समीक्षा में कुछ जानकारी मौजूद नहीं है. जैसे, समीक्षक की पहचान और वह किस डिश के बारे में बता रहा है. अच्छी बात यह है कि आप Bazel की मदद से, यह जानकारी देख सकते हैं. reviews पैकेज में एक ऐसा प्रोग्राम शामिल है जो किसी रहस्यमयी ग्राहक की समीक्षा को प्रिंट करता है. इसे बनाएं और चलाएं:

bazel build //src/main/java/com/example/reviews:review
bazel-bin/src/main/java/com/example/reviews/review

सिर्फ़ बेज़ल क्वेरी पर जाकर, यह जानने की कोशिश करें कि समीक्षा किसने लिखी है और वे किस पकवान के बारे में बता रहे हैं.

संकेत

ज़रूरी जानकारी के लिए, टैग और डिपेंडेंसी देखें.

जवाब

इस समीक्षा में पिज़्ज़ा के बारे में बताया गया था और आमिर में समीक्षक थे. अगर आप देखें कि इस नियम में कौनसी डिपेंडेंसी इस्तेमाल की गई हैं, तो bazel query --noimplicit\_deps 'deps(//src/main/java/com/example/reviews:review)' इस निर्देश से पता चलता है कि समीक्षक समीक्षक हैं! इसके बाद, आपको पता होगा कि समीक्षक आमिर हैं, इसलिए क्वेरी फ़ंक्शन का इस्तेमाल करके यह पता लगाया जा सकता है कि आमिर के पास `बिल्ड` फ़ाइल में कौनसा टैग है, ताकि पता लगाया जा सके कि वहां किस तरह का पकवान है. bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)' का यह निर्देश, सिर्फ़ वह ग्राहक है जिसने पिज़्ज़ा ऑर्डर किया था और वह समीक्षक हैं जो हमें जवाब देते हैं.

रैप किया जा रहा है

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