১. এক নজরে
কোড রিভিউতে ধরা না পড়া বেশিরভাগ SQL বাগ হল অ্যাগ্রিগেশন বাগ। টেবিলে একটি সংখ্যা সঠিক আছে, একটি জয়েন সেটির কপি করে এবং মোট সংখ্যাটি ভুল।
BigQuery Graph আপনাকে একবার প্রপার্টি গ্রাফ হিসেবে টেবিলগুলি কীভাবে কানেক্ট করে তা বর্ণনা করতে এবং তারপরে কানেকশন সম্পর্কে কোয়েরি করতে দেয়। গ্রাফের পরিমাপ সেই বিবরণে আরও একটি জিনিস যোগ করে: অ্যাগ্রিগেশন নিজেই। আপনি MEASURE(SUM(streams)) ঘোষণা করেন সেই নোডে যেটির মালিকানায় নম্বরটি আছে এবং গ্রাফ থেকে ডেটা রিড করা প্রতিটি কোয়েরি সঠিক গ্র্যানুলারিটিতে সঠিক মোট সংখ্যা পায় — কোনও GROUP BY কৌশল নেই, কোনও CTE নেই যা কাউকে মনে রাখতে হবে।
এই কোডল্যাবে আপনি পাঁচটি টেবিল সহ একটি মিউজিক ক্যাটালগ তৈরি করবেন, এতে একটি পরিমাপ যোগ করবেন এবং একই প্রশ্নের দুটি আলাদা উত্তর পেতে দেখবেন: ১২.৬ বিলিয়ন SUM সহ, ৫.১ বিলিয়ন AGG সহ। গ্যাপ হল ক্যাটালগের আকার — কোনও গান চারটি প্লেলিস্টে থাকলে, গ্রাফ ফ্ল্যাট করার পরে সেটি চারটি সারি হয়ে যায় এবং SUM চারটিই যোগ করে। তারপর আপনি সেইসব নিয়ম শিখবেন যেগুলি দ্বিতীয়টিকে সঠিক করে।

আপনি যেখানে টাইপ করবেন
এই ল্যাব ঠিক দুটি জায়গা ব্যবহার করে, এই ক্রমে:
কোথায় | সেখানে আপনি কী করেন | |
1 | Cloud Shell টার্মিনাল | কয়েকটি কমান্ড, শুধুমাত্র সেট-আপ ধাপে |
2 | BigQuery কনসোল | অন্যান্য সব কিছু: কোয়েরি এডিটরে কোয়েরি পেস্ট করা, গ্রাফ মডেলারের মাধ্যমে ক্লিক করা, এজেন্টের সাথে চ্যাট করা |
প্রতিটি নির্দেশাবলী ট্যাগ করা থাকে, যাতে আপনি সবসময় বুঝতে পারেন যে কোনটির কথা বলা হচ্ছে:
- 👉💻 Cloud Shell — Cloud Shell টার্মিনালে এটি টাইপ করুন।
- 👉📋 কোয়েরি এডিটর — এটি BigQuery কোয়েরি এডিটরে পেস্ট করে রান করুন বিকল্পে ক্লিক করুন।
- 👉🌐 কনসোল — BigQuery কনসোলে ক্লিক করে দেখুন। ধাপে কিছু টাইপ করতে বলা না থাকলে, টাইপ করার প্রয়োজন নেই।
- 👀 — ফলাফল দেখুন।
আপনি কী শিখবেন
- ভিজ্যুয়াল গ্রাফ মডেলারে বা SQL-এ নোড টেবিলে কীভাবে কোনও পরিমাপ ঘোষণা করতে হয়
GRAPH_EXPANDকীভাবে গ্রাফকে একটি চওড়া টেবিলে ফ্ল্যাট করেAGGফাংশনটিই কেন একমাত্র ফাংশন যা কোনও পরিমাপ পড়তে পারে এবং অন্যান্য সব প্রচেষ্টা কী বলে- কোনও পরিমাপের ক্ষেত্রে কাজ করে এমন ছয়টি এগ্রিগেট এবং সেগুলির মধ্যে কীভাবে গাণিতিক অপারেশন করতে হয়
- কোনও পরিবর্তন না করে কীভাবে একটি পরিমাপ আলাদাভাবে গ্রুপ করা প্রশ্নের উত্তর দেয়
- ঐচ্ছিক: GQL ও 'গ্রাফ' ট্যাব কীভাবে এমন প্রশ্নের উত্তর দেয় যা মোট উত্তর হতে পারে না এবং BigQuery ডেটা এজেন্ট কীভাবে আপনার পরিমাপ সম্পর্কে না জেনেও তা ব্যবহার করে
আপনার কী প্রয়োজন হবে
- বিলিং উপলভ্য আছে এমন Google অ্যাকাউন্ট ও ব্রাউজার। আপনাকে আগে থেকে Google Cloud প্রোজেক্ট তৈরি করতে হবে না — সেট-আপ আপনার জন্য একটি তৈরি করে দেবে।
- শুধুমাত্র ঐচ্ছিক চ্যাট ধাপের জন্য: Gemini Data Analytics API চালু করা এবং Gemini Data Analytics Data Agent Creator ভূমিকা।
আপনার মেশিনে ইনস্টল করার মতো কিছু নেই। সবকিছু Cloud Shell ও BigQuery কনসোলে রান করে।
প্রোডাক্টের স্ট্যাটাস ও খরচ
BigQuery Graph এখন সাধারণভাবে উপলভ্য। গ্রাফ পরিমাপ, ভিজ্যুয়াল গ্রাফ মডেলর, গ্রাফ ভিজ্যুয়ালাইজেশন এবং ডেটা এজেন্ট নলেজ সোর্স হিসেবে গ্রাফ ব্যবহার করা প্রিভিউতে আছে, যা প্রি-GA অফারিং সংক্রান্ত শর্তাবলীতে অন্তর্ভুক্ত।
GRAPH_EXPAND এবং AGG চাহিদা অনুযায়ী দামের ভিত্তিতে চলে। ডকুমেন্টেশন অনুযায়ী, GQL কোয়েরির (ঐচ্ছিক পাথ স্টেপ) জন্য Enterprise বা Enterprise Plus এডিশন ব্যবহার করে রিজার্ভেশন করতে হয় — সেই কারণেই এই ধাপটি ঐচ্ছিক।
ডেটা সেট কয়েক কিলোবাইট। অন-ডিমান্ড প্রাইসিংয়ের অধীনে প্রতিটি কোয়েরির জন্য ন্যূনতম ১০ এমবি হিসেবে বিল করা হয়, তাই পুরো কোডল্যাবের খরচ এক সেন্টের ভগ্নাংশ।
২. সেট-আপ করুন
এটিই একমাত্র ধাপ যেখানে Cloud Shell ব্যবহার করা হয়। এটি একটি প্রোজেক্ট তৈরি করে, এতে বিলিং সেট করে এবং কাঁচা টেবিল তৈরি করে। BigQuery কনসোলে, গ্রাফ, পরিমাপ ও প্রতিটি কোয়েরি আপনিই রান করাতে পারবেন।
এই ল্যাব আপনাকে একটি জিনিস দিতে পারবে না: বিলিং চালু আছে এমন একটি Google Cloud প্রোজেক্ট। ধাপ ১-এ এমন একটি অ্যাকাউন্ট তৈরি করা হয় যা পেমেন্ট করতে পারে; ধাপ ৪-এ সেই অ্যাকাউন্টটি একটি প্রোজেক্টে পরিণত হয়। এই ক্রমেই সেগুলি করুন — ৪ নম্বর ধাপের পরে প্রতিটি ধাপ ৪ নম্বর ধাপে তৈরি করা প্রোজেক্টটি পড়ে।
১ · বিলিং সহ অ্যাকাউন্ট পান (~১ মিনিট)
👉🌐 অন্য কিছু করার আগে এটি করুন। বিলিং চালু আছে এমন Google অ্যাকাউন্ট দিয়ে সাইন-ইন করুন। এই ধরনের যেকোনও অ্যাকাউন্ট কাজ করে। আপনার যদি না থাকে, তাহলে ফ্রি ট্রায়াল শুরু করুন; এটি আপনাকে একটি বিলিং অ্যাকাউন্ট দেয়, যা ধাপ ৪-এর জন্য প্রয়োজন।
২ · Cloud Shell খুলুন (~১ মিনিট)
👉🌐 কনসোল — Google Cloud কনসোলের সবচেয়ে উপরে Cloud Shell চালু করুন বিকল্পে ক্লিক করুন — এটি হল হেডার অংশে টার্মিনাল-আকৃতির আইকন। পৃষ্ঠার নিচে একটি টার্মিনাল খোলে।

👉🌐 Console — আজ কোনও সময়ে আপনাকে অনুমোদন করতে বলা হলে, চালিয়ে যেতে অনুমোদন করুন বিকল্পে ক্লিক করুন।
👉💻 Cloud Shell — Cloud Shell কোন অ্যাকাউন্ট দিয়ে সাইন-ইন করা আছে তা চেক করুন:
gcloud auth list
👀 আপনার নিজের অ্যাকাউন্টে * চিহ্ন দেখতে পাবেন এবং এটি অবশ্যই প্রথম ধাপে যে অ্যাকাউন্ট দিয়ে সাইন-ইন করেছেন সেটি হতে হবে। এটি না হলে, gcloud auth login রান করান এবং সঠিকটি বেছে নিন।
৩ · ল্যাব (~১ মিনিট) পান
👉💻 Cloud Shell — রেপো ক্লোন করুন:
cd ~
rm -rf ~/bq-graph-measures-lab
git clone https://github.com/cuppibla/bq-graph-measures-lab.git
cd ~/bq-graph-measures-lab
৪ · আপনার প্রোজেক্ট তৈরি করুন (~২ মিনিট)
👉💻 Cloud Shell — একটি স্ক্রিপ্ট আপনার বিলিং অ্যাকাউন্ট খুঁজে পায়, সেটিতে একটি প্রোজেক্ট তৈরি করে এবং Cloud Shell-কে সেই প্রোজেক্টের দিকে নির্দেশ করে:
cd ~/bq-graph-measures-lab
./setup_project.sh
👀 এটি যে বিলিং অ্যাকাউন্ট বেছে নিয়েছে সেটির জন্য প্রত্যাশা করুন, এটি যে প্রোজেক্ট তৈরি করেছে সেটির জন্য ✓ এবং এই ধরনের শেষ বাক্য:✓
Project ready: bq-graph-4271 Next: ./setup.sh
bq-graph-4271 হল আপনার প্রোজেক্ট আইডি — আপনার আইডিতে আলাদা সংখ্যা থাকবে। সেখানে চারটি জিনিস ঘটে:
বিলিং | আপনার কাছে থাকলে সবচেয়ে নতুন | |
প্রোজেক্ট |
| |
বেছে নেয় |
| |
অপেক্ষা করে | নতুন প্রোজেক্ট আসলে পরিবেশন করার অনুমতি না পাওয়া পর্যন্ত, সর্বাধিক দুই মিনিট ধরে পোল | |
🌐 একই প্রোজেক্ট এখন কনসোলে আছে — এর আইডি ড্যাশবোর্ডের প্রোজেক্টের তথ্য কার্ডে আছে:

৫ · ডেটাসেট তৈরি করুন (~৩ মিনিট)
👉💻 Cloud Shell — আরও একটি স্ক্রিপ্ট টেবিল তৈরি করে:
cd ~/bq-graph-measures-lab
./setup.sh
স্ক্রিপ্টটি রান করার সময় প্রতিটি ধাপ প্রিন্ট করে। এটি কী কী করে, সেই ক্রম:
প্রোজেক্ট |
| |
API |
| |
ডেটা সেট | মার্কিন যুক্তরাষ্ট্রের মাল্টি-রিজিয়নে | |
চেক করুন | প্রতিটি টেবিলের সারি গণনা করে এবং কোনও গণনা ভুল হলে বন্ধ হয়ে যায় | |
👀 প্রত্যাশা:
BigQuery Graph Measures · setup ✓ project: bq-graph-4271 ✓ BigQuery API enabled Creating dataset music (US) and five tables... ✓ music.Labels 2 rows ✓ music.Artists 3 rows ✓ music.Songs 5 rows ✓ music.Playlists 4 rows ✓ music.PlaylistEntries 10 rows 🎉 ready — open BigQuery Studio: https://console.cloud.google.com/bigquery?project=bq-graph-4271
Cloud Shell-এর কাজ শেষ। আপনি এটি বন্ধ করে দিতে পারেন।
৬ · BigQuery ও কোয়েরি এডিটর খুলুন
👉🌐 কনসোল — আউটপুটের শেষে থাকা লিঙ্কে ক্লিক করুন অথবা নেভিগেশন মেনু থেকে BigQuery খুলুন। বাঁদিকে এক্সপ্লোরার প্যানেলে, আপনার প্রোজেক্ট বড় করুন: পাঁচটি টেবিল সহ একটি music ডেটাসেট।

👉🌐 কনসোল — BigQuery Studio-র সবচেয়ে উপরে, নতুন তৈরি করুন সারিতে, SQL কোয়েরি বিকল্পে ক্লিক করুন। একটি খালি এডিটর ট্যাব খুলবে।

এই ট্যাবটি রেখে দিন। এই ল্যাবের প্রতিটি 👉📋 ব্লক এখানে যায়: এডিটরে যা আছে তা বেছে নিন, তার উপরে নতুন ব্লক পেস্ট করুন, রান করুন বিকল্পে ক্লিক করুন। নিচের প্যানেলে ফলাফল দেখা যাবে।
টেবিল সম্পর্কে জানুন
এইসব টেবিল সম্পর্কে দুটি বিষয় পরে গুরুত্বপূর্ণ হয়ে ওঠে। প্রতিটি টেবিল তার প্রাইমারি কী NOT ENFORCED হিসেবে ঘোষণা করে: BigQuery এটি চেক করে না, কিন্তু আপনি যে প্রপার্টি গ্রাফ তৈরি করতে চলেছেন, সেটির একটি স্পষ্ট কী প্রয়োজন, যাতে বোঝা যায় যে কোনও সারিকে কী শনাক্ত করে। এবং শেষ টেবিল, PlaylistEntries, হল একটি জাংশন টেবিল: কোনও গান চারটি প্লেলিস্টে থাকলে, এতে চারটি সারি থাকে। ওই টেবিলেই পুরো গল্পটি ঘটে।
টেবিলগুলি এইভাবে একে অপরের সাথে যুক্ত থাকে: একটি লেবেল আর্টিস্টদের সাথে চুক্তি করে, আর্টিস্টরা গান রিলিজ করেন, PlaylistEntries-এর মাধ্যমে কোনও গান প্লেলিস্টে যোগ করা হয়। Cymbal Records-এর মালিকানাধীন Ava Sterling ও Mina Okafor এবং তাদের মাধ্যমে চারটি গান। Northwind Audio-এর মালিকানাধীন হল Kai Nakamura এবং একটি গান, Midnight Drive.
টেবিল | সারি | কী | এতে কী কী থাকে |
লেবেল | 2 |
| নাম, মার্কেটিং বাজেট |
শিল্পী | 3 |
| নাম, কোন লেবেল |
গান | 5 |
| নাম, আর্টিস্ট, স্ট্রিম |
প্লেলিস্ট | 4 |
| নাম, ফলোয়ার |
PlaylistEntries | 10 |
| কোন গান কোন প্লেলিস্টে আছে |
✅ চেকপয়েন্ট: 🎉 ready Cloud Shell-এ, এক্সপ্লোরারের মধ্যে music-এ পাঁচটি টেবিল এবং একটি খালি কোয়েরি এডিটর ট্যাব খোলা আছে।
৩. গ্রাফ তৈরি করা — বিকল্প 'ক': ভিজ্যুয়াল মডেলর
টেবিলগুলি কীভাবে কানেক্ট করে তা প্রপার্টি গ্রাফের মাধ্যমে বর্ণনা করা হয়। আপনি ভিজ্যুয়াল গ্রাফ মডেলারে (এই ধাপ, সবকটি ক্লিক করা) একসাথে ক্লিক করতে পারেন অথবা SQL হিসেবে লিখতে পারেন (পরবর্তী ধাপ, একটি পেস্ট করা)। দুটিই একই অবজেক্ট তৈরি করে — দুটির মধ্যে একটি করুন, দুটিই নয়।
১. গ্রাফ শেল তৈরি করা
👉🌐 কনসোল — BigQuery Studio-তে, নতুন তৈরি করুন সারিতে, AI ও নলেজ মেনু খুলুন এবং গ্রাফ বিকল্পে ক্লিক করুন।
👉🌐 Console — গ্রাফের নাম হিসেবে MusicGraph এবং ডেটাসেটে গ্রাফের গন্তব্য হিসেবে music লিখুন। ডেটা সেট (মার্কিন যুক্তরাষ্ট্র) থেকে অঞ্চল পূরণ করা হয়।
👉🌐 কনসোল — ডেটা সোর্স বিকল্পের মধ্যে, পাঁচটি টেবিল বেছে নিন — আর্টিস্ট, লেবেল, PlaylistEntries, প্লেলিস্ট, গান — এবং তৈরি করুন বিকল্পে ক্লিক করুন।

👀 ক্যানভাসটি পাঁচটি রঙিন নোড সহ খোলে এবং সেগুলির মধ্যে কোনও লাইন থাকে না। ডানদিকে বিবরণ প্যানেলে নোড (৫) ও এজ (০) তালিকাভুক্ত করা আছে। প্রতিটি নোডে ইতিমধ্যেই তার টেবিলের প্রাইমারি কী এবং প্রপার্টি হিসেবে সব কলাম থাকে — সেগুলি দেখতে কোনও নোডে ক্লিক করুন।

২. চারটি প্রান্ত আঁকো
এজ হল একটি ফরেন কী, যা আঁকা হয়। প্রতিটি টেবিল সেই টেবিল থেকে যায় যেখানে কী থাকে এবং সেই টেবিলের দিকে পয়েন্ট করে।
👉🌐 Console — নতুন এজ বিকল্পে ক্লিক করুন। টেবিল বেছে নিন ডায়ালগে, PlaylistEntries বেছে নিয়ে যোগ করুন বিকল্পে ক্লিক করুন। এজ যোগ করুন প্যানেলে:
- নাম
EntryToSongহিসেবে সেট করুন। - প্রাইমারি কী যোগ করুন বিকল্পে ক্লিক করে
entry_idসম্মতি জানান। - সোর্স বিকল্পের মধ্যে, সোর্স নোড-কে PlaylistEntries হিসেবে সেট করুন, তারপর নোডে রেফারেন্স করা কলাম যোগ করুন এবং এজে রেফারেন্স করা কলাম যোগ করুন বিকল্প ব্যবহার করে দুটির জন্যই
entry_idবেছে নিন। - টার্গেট বিকল্পের মধ্যে, টার্গেট নোডকে গান হিসেবে সেট করুন, তারপর নোডে রেফারেন্স করা কলাম ও এজে রেফারেন্স করা কলাম, এই দু'টির জন্যই
song_idবেছে নিন। - হয়ে গেছে বিকল্পে ক্লিক করুন।

👉🌐 কনসোল — আরও তিনবার রিপিট করুন:
এজের নাম | টেবিল | সোর্স নোড → টার্গেট নোড | দু'দিকে বেছে নেওয়ার জন্য কলাম |
| PlaylistEntries | PlaylistEntries → Playlists | সোর্স |
| গান | গান → আর্টিস্ট | সোর্স |
| শিল্পী | আর্টিস্ট → লেবেল | সোর্স |
অতিরিক্ত প্রপার্টি ছাড়াই প্রতিটি প্রান্ত ছেড়ে দিন।
👀 বিবরণ প্যানেলে এখন এজ (৪) লেখা দেখা যাচ্ছে এবং ক্যানভাসে চেইনটি দেখানো হচ্ছে: লেবেল ← আর্টিস্ট ← গান ← প্লেলিস্টএন্ট্রি → প্লেলিস্ট।

৩. মাপ যোগ করুন
👉🌐 Console — গান নোডে ক্লিক করুন, তারপর বিবরণের প্যানেলের উপরে এডিট করুন (পেন্সিল) আইকনে ক্লিক করুন। লেবেলের প্রপার্টি বিকল্পের মধ্যে, প্রপার্টি যোগ করুন, তারপর ফিল্ড যোগ করুন বিকল্পে ক্লিক করুন।
👉🌐 কনসোল — total_streams-কে ফিল্ডের নাম হিসেবে লিখুন এবং এক্সপ্রেশন বক্সে এটি টাইপ করুন:
MEASURE(SUM(streams))
👉🌐 কনসোল — যোগ করুন, তারপর হয়ে গেছে বিকল্পে ক্লিক করুন।

৪. সেটির লেখা কোডটি পড়ে দেখুন, তারপর প্রকাশ করুন
👉🌐 কনসোল — ডানদিকের প্যানেলে কোড ট্যাব খুলুন। মডেলার আপনার জন্য CREATE PROPERTY GRAPH বিবৃতি লিখেছেন। গান নোডে স্ক্রল করুন: এর প্রপার্টি তালিকা এখন
MEASURE(SUM(streams)) AS `total_streams`
এক লাইনে এই হল সম্পূর্ণ ফিচার। এই ধাপের পরে যা কিছু আছে তা হল সেই লাইনটি কী করে।

👉🌐 কনসোল — প্রকাশ করুন বিকল্পে ক্লিক করুন।
✅ চেকপয়েন্ট: এক্সপ্লোরারে, music-এ এখন MusicGraph থাকা গ্রাফ ফোল্ডার আছে। এটিতে ক্লিক করুন: পাঁচটি নোড, চারটি এজ এবং কোড ট্যাবে MEASURE(SUM(streams)) লাইন। পরের ধাপটি এড়িয়ে যান এবং SUM ও AGG, পাশাপাশি বিকল্পে যান।
৪. গ্রাফ তৈরি করা — বিকল্প খ: SQL
আপনি যদি মডেলারে গ্রাফ তৈরি করে থাকেন, তাহলে এই ধাপটি এড়িয়ে যান।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
CREATE OR REPLACE PROPERTY GRAPH music.MusicGraph
NODE TABLES (
music.Labels KEY (label_id)
PROPERTIES (label_id, label_name, marketing_budget,
MEASURE(SUM(marketing_budget)) AS total_budget),
music.Artists KEY (artist_id)
PROPERTIES (artist_id, artist_name, label_id,
MEASURE(COUNT(artist_id)) AS artist_count),
music.Songs KEY (song_id)
PROPERTIES (song_id, title, artist_id, streams,
MEASURE(SUM(streams)) AS total_streams,
MEASURE(COUNT(song_id)) AS song_count),
music.Playlists KEY (playlist_id)
PROPERTIES (playlist_id, playlist_name, followers,
MEASURE(SUM(followers)) AS total_followers),
music.PlaylistEntries KEY (entry_id)
PROPERTIES (entry_id, playlist_id, song_id,
MEASURE(COUNT(entry_id)) AS placement_count)
)
EDGE TABLES (
music.PlaylistEntries AS EntryToSong
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (song_id) REFERENCES Songs(song_id) NO PROPERTIES,
music.PlaylistEntries AS EntryToPlaylist
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (playlist_id) REFERENCES Playlists(playlist_id) NO PROPERTIES,
music.Songs AS SongToArtist
SOURCE KEY (song_id) REFERENCES Songs(song_id)
DESTINATION KEY (artist_id) REFERENCES Artists(artist_id) NO PROPERTIES,
music.Artists AS ArtistToLabel
SOURCE KEY (artist_id) REFERENCES Artists(artist_id)
DESTINATION KEY (label_id) REFERENCES Labels(label_id) NO PROPERTIES
)
👀 ফলাফল প্যানেলে বলা হয়েছে যে প্রপার্টি গ্রাফ তৈরি করা হয়েছে।

এটি একবার পড়ে শোনাও
গ্রাফে পাঁচটি নোড টেবিল ও চারটি এজ টেবিল আছে। প্রতিটি নোড টেবিল তার KEY-এর নাম দেয় এবং PROPERTIES-এর তালিকা তৈরি করে। MEASURE দিয়ে শুরু হওয়া লাইনগুলি হল নতুন অংশ: প্রতিটি লাইন কোনও প্রপার্টির চারপাশে কাজ করে এমন একটি এগ্রিগেটকে র্যাপ করে এবং এটিকে একটি ছদ্মনাম দেয়, যা প্রয়োজন।
প্রতিটি এজ টেবিল হল একটি ফরেন কী, যা এভাবে লেখা হয়: SOURCE KEY যে টেবিলে কী থাকে, DESTINATION KEY যে টেবিলের দিকে এটি পয়েন্ট করে। NO PROPERTIES মানে হল, এজেন্টের নিজস্ব কোনও ডেটা নেই।
লক্ষ্য করুন যে PlaylistEntries তিনবার দেখা যাচ্ছে: একবার নোড টেবিল হিসেবে এবং আরও দুবার EntryToSong ও EntryToPlaylist এজের পেছনের ফিজিক্যাল টেবিল হিসেবে। এটি ইচ্ছাকৃতভাবে করা হয়েছে এবং কেন করা হয়েছে তা আমরা পরে ব্যাখ্যা করব।
তুমি কী তৈরি করেছ তা দেখো
👉🌐 কনসোল — এক্সপ্লোরার প্যানেলে, music, তারপর গ্রাফ বড় করে MusicGraph-এ ক্লিক করুন। পাঁচটি নোড ও চারটি এজ সহ ক্যানভাসের উপর গ্রাফ পৃষ্ঠাটি খোলে। কোনও নোডের প্রপার্টি দেখতে সেটিতে ক্লিক করুন — পরিমাপগুলি তাদের এগ্রিগেট সহ তালিকাভুক্ত করা হয়। ছবির পেছনের স্টেটমেন্ট দেখতে কোড ট্যাব খুলুন।

✅ চেকপয়েন্ট: music-এ Graphs ফোল্ডার আছে যাতে MusicGraph আছে এবং কোড ট্যাবে MEASURE(SUM(streams)) AS total_streams দেখানো হচ্ছে।
৫. SUM ও AGG, পাশাপাশি
এটি হল একটি কোয়েরিতে সম্পূর্ণ কোডল্যাব। দুটি কলামই একই প্রশ্ন — লেবেল পিছু মোট স্ট্রিম — একই টেবিল থেকে উত্তর দেওয়ার চেষ্টা করছে।
GRAPH_EXPAND যে টেবিল তৈরি করে সেটিই এখানে দেখানো হয়। এটি গ্রাফকে ফ্ল্যাট করে: এটি একটি টেবিল থেকে শুরু হয় এবং প্রতিটি এজকে LEFT JOIN হিসেবে বাইরের দিকে ফলো করে, যতক্ষণ না প্রতিটি কানেক্ট করা টেবিল একটি সিঙ্গেল, ওয়াইড ফলাফলে পাশাপাশি বসে। প্রতিটি প্লেসমেন্টের জন্য একটি সারি, প্রতিটি গানের জন্য একটি নয় এবং প্রতিটি কলামের নাম TableLabel_property। কোয়েরি করার আগে এটি দেখে নিন।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
SELECT Labels_label_name, Songs_title, Songs_streams, Playlists_playlist_name
FROM GRAPH_EXPAND("music.MusicGraph")
ORDER BY Songs_title, Playlists_playlist_name
👀 ১০টি সারি থাকবে বলে আশা করা যায় — PlaylistEntries-এর প্রতিটি প্লেসমেন্টের জন্য একটি করে, ঠিক এই ডেটাই Setup লোড করেছে। Neon Summer সেগুলির মধ্যে চারটি দখল করে, এটি যে প্লেলিস্টে থাকে সেখানে একটি করে এবং Songs_streams প্রতিটি প্লেলিস্টে ২,০০০,০০০,০০০ বার শোনা হয়েছে। সারিগুলিতে কোনও সমস্যা নেই; প্লেলিস্টের সংখ্যা সত্যিই চারটি। কিন্তু কোনও গানে থাকা কলাম এখন প্লেসমেন্ট সংক্রান্ত সারিতে পুনরাবৃত্তি করা হচ্ছে এবং এটিই হল সেই সমস্যা যা পরবর্তী কোয়েরি পরিমাপ করে।
এখন তুলনা করা যাক।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
SELECT
Labels_label_name,
SUM(Songs_streams) AS with_sum,
AGG(Songs_total_streams) AS with_agg
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1 ORDER BY 1
👀 ফলাফল:
Labels_label_name | with_sum | with_agg |
Cymbal Records | ১২,৬০০,০০০,০০০ | ৫,১০০,০০০,০০০ |
Northwind Audio | ৯,০০০,০০০,০০০ | ৪,৫০০,০০০,০০০ |

ম্যানুয়ালি চেক করুন। Cymbal-এর চারটি গান ২.০ বিলিয়ন, ১.৫ বিলিয়ন, ১.২ বিলিয়ন ও ০.৪ বিলিয়ন বার স্ট্রিম করা হয়েছে। এটি হল ৫.১ বিলিয়ন। AGG সঠিক। SUM আড়াই গুণ বেশি বড় এবং Northwind-এর একটি গান দ্বিগুণ হয়ে গেছে।
সিনট্যাক্সের তিনটি নতুন অংশ
GRAPH_EXPAND("music.MusicGraph")হল একটি টেবিল-ভ্যালুড ফাংশন যা প্রতিটি এজকেLEFT JOINহিসেবে অনুসরণ করে গ্রাফকে একটি বড় টেবিলে পরিণত করে। প্রতিটি কলামের নামTableLabel_property, তাইSongs_streamsহল Songs টেবিলের র কলাম এবংSongs_total_streamsহল আপনার ঘোষণা করা পরিমাপ।SUM(Songs_streams)হল সেই ওয়াইড টেবিলের উপর সাধারণ SQL — এবং ফ্ল্যাটেনিংয়ের ফলে তৈরি হওয়া প্রতিটি ডুপ্লিকেট এটি ইনহেরিট করে।AGG(Songs_total_streams)যেভাবে ঘোষণা করা হয়েছে সেইভাবে পরিমাপ মূল্যায়ন করে:SUM(streams)song_idপিছু একবার, ওয়াইড টেবিলে কোনও গান যতগুলি সারি জুড়ে থাকুক না কেন।
✅ চেকপয়েন্ট: দুটি লেবেল, দুটি কলাম এবং with_agg সংখ্যা হাতের আঙুল গণনার সাথে ম্যাচ করছে।
৬. SUM কেন বেশি গণনা করে
একটি গান নিয়ে দেখুন যে সেই জোনের জন্য সেটি কেমন হয়।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
SELECT 'BEFORE - the Songs table' AS step, title, streams, CAST(NULL AS STRING) AS playlist
FROM music.Songs WHERE title = 'Neon Summer'
UNION ALL
SELECT 'AFTER - joined to playlists', s.title, s.streams, pl.playlist_name
FROM music.Songs s
LEFT JOIN music.PlaylistEntries e ON e.song_id = s.song_id
LEFT JOIN music.Playlists pl ON pl.playlist_id = e.playlist_id
WHERE s.title = 'Neon Summer'
ORDER BY step DESC, playlist
👀 ফলাফল:
ধাপ | শীর্ষক | স্ট্রিম | প্লেলিস্ট |
আগে - Songs টেবিল | নিয়ন সামার | ২,০০০,০০০,০০০ | নাল |
AFTER - joined to playlists | নিয়ন সামার | ২,০০০,০০০,০০০ | জিম পাম্প |
AFTER - joined to playlists | নিয়ন সামার | ২,০০০,০০০,০০০ | এই মুহূর্তে জনপ্রিয় |
AFTER - joined to playlists | নিয়ন সামার | ২,০০০,০০০,০০০ | রাইজিং পপ |
AFTER - joined to playlists | নিয়ন সামার | ২,০০০,০০০,০০০ | রোড ট্রিপ |

একটি সারি চারটি হয়ে গেছে। স্ট্রিমের সংখ্যায় কোনও পরিবর্তন হয়নি — এটি কপি করা হয়েছে। Cymbal Records-এর কপি করা কন্টেন্ট থেকে কত উপার্জন হয়েছে তা যোগ করুন: চারটি প্লেলিস্টে Neon Summer 2.0 বিলিয়ন হলে ৮.০, দু'টি প্লেলিস্টে Paper Crown 1.5 বিলিয়ন হলে ৩.০, একটি প্লেলিস্টে Double Shot 1.2 বিলিয়ন হলে ১.২, একটি প্লেলিস্টে Slow Arrow 0.4 বিলিয়ন হলে ০.৪। এটি হল ১২.৬ বিলিয়ন, এই সংখ্যাটি SUM ফেরত দিয়েছে। Northwind's Midnight Drive দুটি প্লেলিস্টে আছে, তাই ৪.৫ বিলিয়ন ভিউ ৯.০ বিলিয়ন হয়ে গেছে।
এটি ফ্যান-আউট এবং এটি যোগ দেওয়ার ক্ষেত্রে কোনও বাগ নয়। প্লেলিস্টের সারিগুলি আসল। প্লেসমেন্টের সাথে সম্পর্কিত সারিতে থাকা কোনও গানের সাথে সম্পর্কিত সংখ্যা যোগ করা হয়েছে।
এই পরিমাপটি এটি ঠিক করে দেয় কারণ এটি KEY (song_id)-এর সাথে Songs নোডে ঘোষণা করা হয়েছে। মূল বিষয় হল, কন্টেন্টের ধরন। AGG যখন total_streams মূল্যায়ন করে, তখন এটি প্রতি মিউজিক কী একবার করে এগ্রিগেট করে এবং তারপরে আপনি যা দিয়ে গ্রুপ করেছেন সেটিতে রোল-আপ করে।
কী কী পরিবর্তন হয়েছে
আপনি যা লিখতেন | পরিমাপ সহ |
| গ্রাফে |
|
|
তিনটি |
|
যোগদান করার আগে এগ্রিগেট করা একটি CTE | কিছুই না। |
✅ চেকপয়েন্ট: পাঁচটি সারি — একটি আগে, চারটি পরে — এবং আপনি এগুলি থেকে ১২.৬ বিলিয়ন রিকনস্ট্রাক্ট করতে পারবেন।
৭. নিয়ম: শুধুমাত্র AGG একটি পরিমাপ পড়ে
মেজারমেন্টের নিজস্ব ধরন, MEASURE থাকে এবং ঠিক একটি ফাংশন এটি গ্রহণ করে। নিচে দেওয়া চারটি কোয়েরি উদ্দেশ্যপ্রণোদিতভাবে কাজ করে না — প্রতিটি কোয়েরি রান করান এবং লাল রঙের সমস্যাটি পড়ুন। এই চারটি উপায় সবাই প্রথমে চেষ্টা করে এবং সেগুলি কী বলে তা জানলে পরে সময় বাঁচে।
👉📋 কোয়েরি এডিটর — AGG সাধারণ কলামে:
SELECT AGG(Songs_streams) FROM GRAPH_EXPAND("music.MusicGraph")
👀 No matching signature for aggregate function AGG ... Argument 1: expected MEASURE

👉📋 কোয়েরি এডিটর — AGG ছাড়া পরিমাপ কলাম:
SELECT Songs_total_streams FROM GRAPH_EXPAND("music.MusicGraph") LIMIT 1
👀 Returning expressions of type MEASURE is not allowed

👉📋 কোয়েরি এডিটর — GQL-এ উল্লেখ করা একটি পরিমাপ, যা কখনও পরিমাপ দেখতে পায় না (এটি একটি GQL কোয়েরি — ওভারভিউতে এডিট করা নোট দেখুন):
GRAPH music.MusicGraph
MATCH (s:Songs)
RETURN s.total_streams
LIMIT 1
👀 total_streams is not exposed by element type GRAPH_NODE(...)

👉📋 কোয়েরি এডিটর — SUM পরিমাপ কলামের উপরে, সবচেয়ে আকর্ষণীয়:
SELECT Labels_label_name, SUM(Songs_total_streams)
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
👀 MEASURE-typed arguments are only permitted in the AGG function

তাই টাইপ সিস্টেম আপনার জন্য নিয়ম প্রয়োগ করে। GRAPH_EXPAND-এর মাধ্যমে কোনও পরিমাপ শুধুমাত্র দেখা যায় এবং AGG-এর মাধ্যমে শুধুমাত্র পড়া যায়। আগে থেকে অতিরিক্ত গণনা করা ১২.৬ বিলিয়ন শুধুমাত্র কাঁচা কলাম যোগ করে পাওয়া যেতে পারে — কখনওই ভুলভাবে ম্যানেজ করা পরিমাপ থেকে নয়।
✅ চেকপয়েন্ট: চারটি লাল রঙের এরর এবং আপনি বলতে পারবেন যে প্রতিটি এরর কোন নিয়ম প্রয়োগ করছে।
৮. প্রতিটি এগ্রিগেট একটি পরিমাপ সমর্থন করে
MEASURE() ছয়টি অ্যাগ্রিগেটের মধ্যে একটিকে র্যাপ করে: SUM, AVG, MIN, MAX, COUNT এবং COUNT(DISTINCT). Songs নোডে সব ছ'টি নিয়ে গ্রাফটি আবার তৈরি করুন। এজ NO PROPERTIES থাকে, এটি হল ডকুমেন্ট করা সবচেয়ে ভালো প্র্যাক্টিস যখন কোনও এজ তার ফিজিক্যাল টেবিল কোনও নোডের সাথে শেয়ার করে।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
CREATE OR REPLACE PROPERTY GRAPH music.MusicGraph
NODE TABLES (
music.Labels KEY (label_id)
PROPERTIES (label_id, label_name, marketing_budget,
MEASURE(SUM(marketing_budget)) AS total_budget),
music.Artists KEY (artist_id)
PROPERTIES (artist_id, artist_name, label_id,
MEASURE(COUNT(artist_id)) AS artist_count),
music.Songs KEY (song_id)
PROPERTIES (song_id, title, artist_id, streams,
MEASURE(SUM(streams)) AS total_streams,
MEASURE(AVG(streams)) AS avg_streams,
MEASURE(MIN(streams)) AS min_streams,
MEASURE(MAX(streams)) AS max_streams,
MEASURE(COUNT(song_id)) AS song_count,
MEASURE(COUNT(DISTINCT artist_id)) AS distinct_artists),
music.Playlists KEY (playlist_id)
PROPERTIES (playlist_id, playlist_name, followers,
MEASURE(SUM(followers)) AS total_followers),
music.PlaylistEntries KEY (entry_id)
PROPERTIES (entry_id, playlist_id, song_id,
MEASURE(COUNT(entry_id)) AS placement_count)
)
EDGE TABLES (
music.PlaylistEntries AS EntryToSong
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (song_id) REFERENCES Songs(song_id) NO PROPERTIES,
music.PlaylistEntries AS EntryToPlaylist
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (playlist_id) REFERENCES Playlists(playlist_id) NO PROPERTIES,
music.Songs AS SongToArtist
SOURCE KEY (song_id) REFERENCES Songs(song_id)
DESTINATION KEY (artist_id) REFERENCES Artists(artist_id) NO PROPERTIES,
music.Artists AS ArtistToLabel
SOURCE KEY (artist_id) REFERENCES Artists(artist_id)
DESTINATION KEY (label_id) REFERENCES Labels(label_id) NO PROPERTIES
)

এখন সেগুলি সব পড়ে শোনান। প্রতিটি পরিমাপ AGG-এর মধ্য দিয়ে যায় এবং শেষ কলামে দেখানো হয় যে AGG ফলাফল হল সাধারণ ভ্যালু যা দিয়ে আপনি গাণিতিক গণনা করতে পারবেন। গ্রাফটি এইমাত্র পরিবর্তন করা হয়েছে, তাই প্রথমে ক্যাশে করা ফলাফল ব্যবহার করুন বিকল্পটি মুছে দিন (আরও → কোয়েরি সেটিংস)।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
SELECT
Labels_label_name,
AGG(Songs_total_streams) AS total_streams,
AGG(Songs_avg_streams) AS avg_streams,
AGG(Songs_min_streams) AS min_streams,
AGG(Songs_max_streams) AS max_streams,
AGG(Songs_song_count) AS songs,
AGG(Songs_distinct_artists) AS artists,
AGG(Songs_total_streams) / AGG(Songs_song_count) AS streams_per_song
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
ORDER BY 1
👀 ফলাফল:
Labels_label_name | total_streams | avg_streams | min_streams | max_streams | গানগুলো | শিল্পী | streams_per_song |
Cymbal Records | ৫,১০০,০০০,০০০ | ১,২৭৫,০০০,০০০ | ৪০০,০০০,০০০ | ২,০০০,০০০,০০০ | 4 | 2 | ১,২৭৫,০০০,০০০ |
Northwind Audio | ৪,৫০০,০০০,০০০ | ৪,৫০০,০০০,০০০ | ৪,৫০০,০০০,০০০ | ৪,৫০০,০০০,০০০ | 1 | 1 | ৪,৫০০,০০০,০০০ |

Cymbal-এর জন্য প্রতিটি সংখ্যা চারটি গান এবং Northwind-এর জন্য একটি গান নিয়ে গণনা করা হয় — দশটি প্লেসমেন্ট রো নিয়ে নয়। AVG-এর ক্ষেত্রে অন্যভাবে হিসেব করলে ভুল উত্তর পাওয়া যেত: প্লেসমেন্ট রোয়ের উপর ভিত্তি করে কাঁচা কলামের গড় মান বের করলে Cymbal-এর জন্য ১.৫৭৫ বিলিয়ন পাওয়া যায়, কারণ Neon Summer-এর ২ বিলিয়ন চারবার গণনা করা হয়।
তাই "SUM-এর পরিবর্তে AGG ব্যবহার করো" আসলে দুটি সিদ্ধান্ত। আপনি কোনও পরিমাপ ঘোষণা করার সময়, সেটি কোন ছ'টি এগ্রিগেট তা বেছে নেন। আপনি সেটি পড়লে, ফাংশনটি সবসময় AGG হয়।
✅ চেকপয়েন্ট: লেবেল পিছু একটি করে সারি, প্রতিটি সারিতে সাতটি করে সংখ্যা এবং streams_per_song ও avg_streams সমান।
৯. গ্রুপিং পরিবর্তন করুন, পরিমাপ নয়
একই পরিমাপ অন্য একটি প্রশ্নের উত্তর দেয়। লেবেলের পরিবর্তে প্লেলিস্ট অনুযায়ী গ্রুপ করুন।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
SELECT
Playlists_playlist_name,
AGG(Songs_total_streams) AS streams,
AGG(Songs_song_count) AS songs
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
ORDER BY 2 DESC
👀 ফলাফল:
Playlists_playlist_name | স্ট্রিম | গানগুলো |
রোড ট্রিপ | ৬,৯০০,০০০,০০০ | 3 |
জিম পাম্প | ৬,৫০০,০০০,০০০ | 2 |
এই মুহূর্তে জনপ্রিয় | ৪,৭০০,০০০,০০০ | 3 |
রাইজিং পপ | ৩,৫০০,০০০,০০০ | 2 |

দুটি AGG লাইন SUM ও AGG থেকে নেওয়া হয়েছে, বাইট-বাই-বাইট, পাশাপাশি। শুধুমাত্র GROUP BY সরানো হয়েছে। Road Trip প্লেলিস্টে Neon Summer, Midnight Drive ও Slow Arrow আছে এবং প্রতিটি গানকে একবার করে গণনা করা হয় — "এই প্লেলিস্টে স্ট্রিম করা হয়েছে" বলতে ঠিক এটিই বোঝানো উচিত।
যে ব্যক্তি পরিমাপ লিখেছেন তিনি একবার শস্য নির্ধারণ করেছেন। পরবর্তীকালে যে কেউ কোয়েরি করলে, সেটি আগের কোয়েরির প্রসঙ্গ ধরে চলে।
✅ চেকপয়েন্ট: ৬.৯ বিলিয়ন ভিউ সহ রোড ট্রিপ সবচেয়ে উপরে আছে।
১০. GRAPH_EXPAND কী কী দেয় তা দেখুন
এর আকার জানতে আপনাকে GRAPH_EXPAND চালাতে হবে না। BQ.SHOW_GRAPH_EXPAND_SCHEMA সিস্টেম প্রসিডিউর, কলামের তালিকা একটি ভেরিয়েবেলে লেখে।
👉📋 কোয়েরি এডিটর — তিনটি লাইনই পেস্ট করুন, তারপর রান করুন বিকল্পে ক্লিক করুন:
DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('music.MusicGraph', schema);
SELECT schema;
👀 ফলাফল হল একটি JSON স্ট্রিং। প্রতিটি ফিল্ডের একটি নাম, ধরন ও মোড থাকে এবং প্রতিটি পরিমাপ কলামে "is_measure": true থাকে। আপনি যে গ্রাফটি তৈরি করেছেন তার জন্য, আপনি এগুলি সহ আরও অনেক কিছু পাবেন:
নাম | ধরন | is_measure | |
Songs_title | STRING | ||
Songs_streams | INTEGER | ||
Songs_total_streams | INTEGER | সত্য | |
Songs_avg_streams | FLOAT | সত্য | |
Songs_distinct_artists | INTEGER | সত্য | |
PlaylistEntries_placement_count | INTEGER | সত্য | |

এছাড়াও, কোনও প্রপার্টিতে আপনার সেট করা যেকোনও বিবরণ বা সমার্থক শব্দ এখানে দেখা যাবে। ঐচ্ছিক চ্যাট ধাপে কারা সেগুলি পড়েন তা দেখানো হয়।
✅ চেকপয়েন্ট: MEASURE দিয়ে ঘোষণা করা প্রতিটি কলামে is_measure সহ JSON স্ট্রিং।
১১. গ্রাফের আকার থেকে GRAPH_EXPAND কী চায়
এই ধাপে চালানোর মতো কিছু নেই — শুধু পড়ুন। GRAPH_EXPAND একটি টেবিল থেকে শুরু করে বাইরের দিকে এজের মাধ্যমে LEFT JOIN-এর চেনের সাহায্যে এর ওয়াইড টেবিল তৈরি করে। এর থেকে তিনটি নিয়ম তৈরি হয় এবং MusicGraph সেগুলি সবই মেনে চলে।

ঠিক একটি রুট নোড টেবিল। রুট হল নোড টেবিল যার কী অন্য কোনও টেবিলে দেখা যায় না — এমন একটি টেবিল যার দিকে কোনও এজ পয়েন্ট করে না। MusicGraph-এ যা হল PlaylistEntries: দুটি এজের সোর্স এবং কোনওটিরই ডেস্টিনেশন নয়। ওয়াইড টেবিলে ১০টি সারি আছে, প্রতিটি প্লেসমেন্টের জন্য একটি করে।
প্রতিটি এজ হল একাধিক-থেকে-এক, সোর্স থেকে ডেস্টিনেশন। প্রতিটি এন্ট্রিতে একটি গান ও একটি প্লেলিস্ট আছে, প্রতিটি গানে একজন আর্টিস্ট আছেন, প্রতিটি আর্টিস্টের একটি লেবেল আছে। এই কারণেই ওয়াইড টেবিল কখনওই রুট টেবিলের নিজস্ব সারির বাইরে যায় না। রুট যে ডেটা অ্যাক্সেস করতে পারে না, তা দেখানো হয় না: প্লেসমেন্ট নেই এমন কোনও গান বড় টেবিল থেকে বাদ দেওয়া হবে।
অনেক-থেকে-অনেকের মধ্যে সম্পর্ক একটি নোড হয়ে যায়। গান ও প্লেলিস্ট হল 'মাল্টিপল-টু-মাল্টিপল'। আপনি যদি জাংশন টেবিলকে Songs থেকে Playlists-এ একটি এজের হিসেবে ঘোষণা করেন, তাহলে GRAPH_EXPAND এটিকে অস্পষ্ট হিসেবে উপেক্ষা করবে — এবং কোনও ব্যবহারযোগ্য এজ না থাকার কারণে এটি কাজ করবে না। PlaylistEntries-কে এমন নোড টেবিলে প্রমোট করা যেখানে সেটির থেকে বেরোনো অনেক-থেকে-এক এজ আছে, এটি হল ডকুমেন্ট করা প্যাটার্ন এবং আপনি গ্রাফ তৈরি করার সময় এটিই করেছেন।
১২. (ঐচ্ছিক) GQL সহ পাথ
এতক্ষণ পর্যন্ত প্রতিটি প্রশ্নের উত্তর সংখ্যায় ছিল। এটিতে তা নেই। Cymbal-এর স্ট্রিম শ্রোতাদের কাছে কোথায় পৌঁছায়? হল গ্রাফের মাধ্যমে রুট সংক্রান্ত প্রশ্ন এবং যোগফল দিয়ে এর উত্তর দেওয়া যায় না — যোগ করার সময় রুটটি আর থাকে না।
১. স্ট্রিম কোথায় ল্যান্ড করে তা জিজ্ঞাসা করুন
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
GRAPH music.MusicGraph
MATCH (l:Labels)<-[:ArtistToLabel]-(a:Artists)<-[:SongToArtist]-(s:Songs)
<-[:EntryToSong]-(e:PlaylistEntries)-[:EntryToPlaylist]->(pl:Playlists)
WHERE l.label_name = 'Cymbal Records'
RETURN pl.playlist_name, pl.followers,
SUM(s.streams) AS streams_reaching_this_playlist,
STRING_AGG(s.title, ', ') AS songs
GROUP BY pl.playlist_name, pl.followers
ORDER BY streams_reaching_this_playlist DESC
👀 চারটি প্লেলিস্ট থাকবে:
pl.playlist_name | pl.followers | streams_reaching_this_playlist | গানগুলো |
এই মুহূর্তে জনপ্রিয় | ৩,৫০,০০,০০০ | ৪,৭০০,০০০,০০০ | ডবল শট, নিয়ন সামার, পেপার ক্রাউন |
রাইজিং পপ | ২,০০০,০০০ | ৩,৫০০,০০০,০০০ | নিয়ন সামার, পেপার ক্রাউন |
রোড ট্রিপ | ৫,০০০,০০০ | ২,৪০০,০০০,০০০ | Neon Summer, Slow Arrow |
জিম পাম্প | ৩,০০০,০০০ | ২,০০০,০০০,০০০ | নিয়ন সামার |

MATCH লাইনটি একটি বাক্য হিসেবে পড়ুন: লেবেল থেকে শুরু করে আর্টিস্টের কাছে যান, তারপর তাদের গানে, তারপর সেইসব গানের প্লেলিস্ট এন্ট্রিতে, তারপর প্লেলিস্টে যান। তীরচিহ্নগুলি যে উপায়ে প্রান্তগুলি ঘোষণা করা হয়েছে তা নির্দেশ করে; <- একটি ধাপ পিছনের দিকে হাঁটে।
এখন তৃতীয় কলামের সংখ্যাগুলি যোগ করুন। ১২.৬ বিলিয়ন — SUM-এর দেওয়া চতুর্থ ধাপের সংখ্যাটি, যেটি ভুল ছিল।
এখানে এটি সঠিক। তখন প্রশ্ন ছিল Cymbal-এ কতবার স্ট্রিম করা হয়েছে এবং কোনও প্লেলিস্টে যতবারই থাকুক না কেন, একটি গান একবারই গণনা করা হত। এই প্রশ্নের উত্তর হল, সেইসব স্ট্রিম যেখানে পৌঁছায় এবং চারটি প্লেলিস্টে থাকা কোনও গান সত্যিই চারজন দর্শকের কাছে পৌঁছায়। GRAPH_EXPAND-এর তৈরি করা ডুপ্লিকেট কন্টেন্ট একটি প্রশ্নের ক্ষেত্রে ভুল এবং অন্যটির ক্ষেত্রে উত্তর। AGG কখনওই ডুপ্লিকেট উত্তর খারাপ হওয়া নিয়ে ছিল না — এটি ছিল প্রশ্নের সাথে অঙ্ক মেলানো নিয়ে।
২. পাথগুলিই রিটার্ন করে
মোট সংখ্যা বাদ দিয়ে রুট সম্পর্কে জিজ্ঞাসা করুন।
👉📋 কোয়েরি এডিটর — পেস্ট করে রান করুন বিকল্পে ক্লিক করুন:
GRAPH music.MusicGraph
MATCH p = (l:Labels)<-[:ArtistToLabel]-(a:Artists)<-[:SongToArtist]-(s:Songs)
<-[:EntryToSong]-(e:PlaylistEntries)-[:EntryToPlaylist]->(pl:Playlists)
WHERE l.label_name = 'Cymbal Records'
RETURN TO_JSON(p) AS path
p = সম্পূর্ণ ম্যাচটির নাম দেয় এবং TO_JSON সেটি রেন্ডার করে।
👀 ৮টি সারি, একটি path কলাম থাকবে বলে আশা করা যায়। প্রতিটি সেল হল একটি রুট বরাবর নোড ও এজের JSON অ্যারে, প্রতিটি নোডে তার labels ও properties থাকে।

চারটি গানের জন্য আটটি সারি, কারণ প্রতিটি প্লেসমেন্টের জন্য একটি করে রুট আছে, প্রতিটি গানের জন্য নয়।
৩. গ্রাফ ট্যাব খুলুন
👉🌐 কনসোল — ফলাফলের উপরে, গ্রাফ বিকল্পে ক্লিক করুন।
ফলাফলে গ্রাফ এলিমেন্ট থাকলে তবেই এই ট্যাব দেখা যায়। আগের কোয়েরি থেকে সংখ্যা পাওয়া গেছে, তাই এতে কোনও গ্রাফ ট্যাব ছিল না; এটি থেকে পাথ পাওয়া গেছে, তাই এতে গ্রাফ ট্যাব আছে।

আপনি গ্রাফের Cymbal-এর কোণটি ফোর্স লেআউট হিসেবে আঁকা দেখতে পাবেন, সাথে ভিউতে থাকা নোড ও এজের সংখ্যা এবং লেবেল পিছু একটি করে চিপ দেখতে পাবেন। লেআউট আলাদা করতে কোনও নোড টেনে আনুন; এর প্রপার্টি পড়তে কোনও একটিতে ক্লিক করুন।
✅ চেকপয়েন্ট: প্রথম কোয়েরির তৃতীয় কলামের যোগফল হল ১২.৬ বিলিয়ন, দ্বিতীয় কোয়েরি ৮টি পাথ রিটার্ন করে এবং Graph ট্যাব সেগুলি আঁকে।
১৩. (ঐচ্ছিক) গ্রাফের সাথে চ্যাট করা
এই ধাপে কোনও SQL নেই। BigQuery ডেটা এজেন্ট তাদের জ্ঞানের সোর্স হিসেবে গ্রাফ ব্যবহার করতে পারে এবং ডকুমেন্টেশনে বলা হয়েছে যে তারা মাল্টি-লেভেল অ্যাগ্রিগেশনের জন্য পরিমাপ ব্যবহার করে। দেখা যাক এটি সত্যি কিনা।
১. এজেন্ট তৈরি করা
👉🌐 কনসোল — বাঁদিকে BigQuery নেভিগেশন মেনুতে, এজেন্ট, তারপর এজেন্ট ক্যাটালগ, তারপর এজেন্ট তৈরি করুন বিকল্পে ক্লিক করুন।
👉🌐 কনসোল — এজেন্টের নাম-এ Music graph agent টাইপ করুন এবং এটি এজেন্টের বিবরণে:
Ask questions about labels, artists, songs and playlists in the music property graph.
👉🌐 কনসোল — তথ্যের সোর্স বিকল্পের মধ্যে, সোর্স যোগ করুন বিকল্পে ক্লিক করুন। সোর্স বেছে নিন ডায়ালগে, আপনার প্রোজেক্ট, music, গ্রাফ প্রসারিত করুন, MusicGraph-এ টিকচিহ্ন দিন এবং কনফার্ম করুন বিকল্পে ক্লিক করুন।
👀 সোর্স যোগ করুন বোতামটি ধূসর হয়ে যায়। একজন এজেন্ট সর্বাধিক একটি গ্রাফ হোল্ডে রাখতে পারেন এবং টেবিলের সাথে গ্রাফ মিশিয়ে দিতে পারেন না।

👉🌐 কনসোল — গ্রাফের লোকেশন থেকে যেভাবে সেট করা হয়েছিল, অঞ্চল সেভাবেই রেখে দিন। সেভ করুন, তারপর প্রকাশ করুন বিকল্পে ক্লিক করুন। প্রকাশনা চ্যানেল প্যানেলে, প্রকাশনা এজেন্ট বিকল্পে ক্লিক করুন এবং কনফার্মেশন মেসেজটি বন্ধ করুন।
২. প্রশ্ন জিজ্ঞাসা করুন
👉🌐 Console — কথোপকথন তৈরি করুন বিকল্পে ক্লিক করুন। একটি চ্যাট পৃষ্ঠা খুলবে। নিচে প্রশ্ন করুন বক্সে এটি টাইপ করে Enter টিপুন:
For each label, show total streams and how many playlists their songs are on
👀 এজেন্ট একটি টেবিল ও এক বাক্যের সারসংক্ষেপ রিটার্ন করে:
label_name | total_streams | playlist_placements |
Cymbal Records | ৫,১০০,০০০,০০০ | 8 |
Northwind Audio | ৪,৫০০,০০০,০০০ | 2 |

৫.১ বিলিয়ন। এজেন্টকে ফ্যান-আউট সম্পর্কে কেউ বলেনি এবং এটি এতে পড়ে না।
৩. সেটির লেখা কোয়েরিটি পড়ুন
👉🌐 Console — নেভিগেশন মেনুতে, জব এক্সপ্লোরার বিকল্পে ক্লিক করে সবচেয়ে নতুন জবটিতে ক্লিক করুন। এটির লেবেলে আপনার এজেন্টের আইডি সহ ca-bq-job: true ও data-agent-id আছে এবং এটির কোয়েরি হল:
SELECT
Labels_label_name AS label_name,
AGG(Songs_total_streams) AS total_streams,
AGG(PlaylistEntries_placement_count) AS playlist_placements
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY label_name
ORDER BY total_streams DESC

এটি নিজে থেকেই GRAPH_EXPAND ও AGG ব্যবহার করেছে, কারণ এটি যে স্কিমা পড়েছে তাতে এই পরিমাপগুলি ছিল। এজেন্টের বিবরণে তার কোনও উল্লেখ নেই।
✅ চেকপয়েন্ট: চ্যাটে দেওয়া উত্তরে ৫.১ বিলিয়ন এবং জবের SQL-এ AGG(...)।
১৪. অপ্রয়োজনীয়গুলি মুছুন
👉💻 Cloud Shell — ডেটাসেট, এর টেবিল ও প্রপার্টি গ্রাফ সরিয়ে দিন:
cd ~/bq-graph-measures-lab
./cleanup.sh
👀 ✓ dropped YOUR_PROJECT_ID.music (tables and graph) হতে পারে।
আপনি ঐচ্ছিক ডেটা এজেন্ট তৈরি করে থাকলে, কনসোলে এজেন্ট → এজেন্ট ক্যাটালগ বিকল্পের অধীনে এটি মুছে দিন। আর ./setup_project.sh যদি এই ল্যাবের জন্যই কোনও প্রোজেক্ট তৈরি করে থাকে, তাহলে সবচেয়ে পরিচ্ছন্নভাবে সব মুছে ফেলার উপায় হল পুরো প্রোজেক্ট বন্ধ করে দেওয়া — আইডিটি ~/project_id.txt-এ আছে।
১৫. অভিনন্দন
আপনি একটি লাইন, MEASURE(SUM(streams)), ঘোষণা করেছেন এবং এটি ১২.৬ বিলিয়নকে ৫.১ বিলিয়নে পরিবর্তন করেছে — আপনার জন্য এবং সেই গ্রাফের বিরুদ্ধে পরে এজেন্ট সহ যে কেউ কোয়েরি লিখুক না কেন, তার জন্য।
আপনি কী শিখেছেন
- কোনও নোডে ঘোষণা করা একটি অ্যাগ্রিগেট হল পরিমাপ, যা
KEY-এর ঠিক পাশে থাকে এবং এর গ্রেন সেট করে। GRAPH_EXPANDগ্রাফটিকেTableLabel_propertyকলাম সহ একটি চওড়া টেবিলে ফ্ল্যাট করে।AGGহল একমাত্র ফাংশন যা কোনও পরিমাপ রিড করে এবং টাইপ সিস্টেম এটিকে চারটি আলাদা আলাদা উপায়ে এনফোর্স করে।- ছ'টি অ্যাগ্রিগেট উপলভ্য এবং
AGGফলাফল হল সাধারণ মান যা আপনি ভাগ করতে পারেন। GROUP BYপরিবর্তন করলে, পরিমাপ না করেই প্রশ্নটি আবার জিজ্ঞাসা করা হয়।GRAPH_EXPANDএকটি রুট, একাধিক-থেকে-একটি প্রান্ত এবং জাংশন নোডে প্রমোট করতে চায়।
সিদ্ধান্তের টেবিল
সমস্যার উপসর্গ | কারণ | এর সমাধান করুন |
মোট সংখ্যাটি অনেক বেশি |
| একটি পরিমাপ ঘোষণা করুন, |
"প্রত্যাশিত MEASURE, পাওয়া গেছে INT64" |
|
|
"MEASURE ধরনের এক্সপ্রেশন রিটার্ন করা যায় না" |
| এটি র্যাপ করুন: |
"এলিমেন্টের ধরন অনুযায়ী এক্সপোজ করা হয়নি" | GQL-এ উল্লেখ করা পরিমাপ |
|
| জংশনটি এজ হিসেবে মডেল করা হয়েছে | জাংশন টেবিলকে নোডে প্রমোট করা |
গ্রাফ পরিবর্তন করার পরে পুরনো নম্বর | ক্যাশে করা ফলাফল | ক্যাশে করা ফলাফল ব্যবহার করুন বিকল্পে টিকচিহ্ন দিন |
আমরা কী কী বিষয় কভার করিনি (উদ্দেশ্যমূলকভাবে)
প্রপার্টির বিবরণ ও সমার্থক শব্দ · ডেটা এজেন্টের জন্য যাচাই করা কোয়েরি ও পরিভাষা · একটির বেশি GQL MATCH · একাধিক গ্রাফ জুড়ে পরিমাপ। প্রতিটিই এক একটি ল্যাব।
আরও জানুন
- মেজার নিয়ে কাজ করা
- প্রপার্টি গ্রাফ তৈরি ও কোয়েরি করা
- কথোপকথন সংক্রান্ত অ্যানালিটিক্স ওভারভিউ
- ল্যাব রেপো — এই কোডল্যাবের প্রতিটি কোয়েরি, ধাপ অনুযায়ী নম্বর করা আছে