1. সংক্ষিপ্ত বিবরণ
স্প্যানার একটি সম্পূর্ণরূপে পরিচালিত, অনুভূমিকভাবে স্কেলেবল, বিশ্বব্যাপী বিতরণযোগ্য ডাটাবেস পরিষেবা যা রিলেশনাল এবং নন-রিলেশনাল উভয় ধরণের অপারেশনাল ওয়ার্কলোডের জন্য দুর্দান্ত। এর মূল ক্ষমতার বাইরে, স্প্যানার শক্তিশালী উন্নত বৈশিষ্ট্যগুলি অফার করে যা বুদ্ধিমান এবং ডেটা-চালিত অ্যাপ্লিকেশন তৈরি করতে সক্ষম করে।
এই কোডল্যাবটি স্প্যানারের মৌলিক ধারণার উপর ভিত্তি করে তৈরি এবং একটি অনলাইন ব্যাংকিং অ্যাপ্লিকেশন ব্যবহার করে আপনার ডেটা প্রক্রিয়াকরণ এবং বিশ্লেষণাত্মক ক্ষমতা উন্নত করার জন্য এর উন্নত ইন্টিগ্রেশনগুলিকে কাজে লাগানোর চেষ্টা করে।
আমরা তিনটি মূল উন্নত বৈশিষ্ট্যের উপর আলোকপাত করব:
- ভার্টেক্স এআই ইন্টিগ্রেশন : গুগল ক্লাউডের এআই প্ল্যাটফর্ম, ভার্টেক্স এআই-এর সাথে স্প্যানারকে কীভাবে নির্বিঘ্নে একীভূত করা যায় তা আবিষ্কার করুন। আপনি শিখবেন কীভাবে স্প্যানার এসকিউএল কোয়েরির মধ্যে থেকে সরাসরি ভার্টেক্স এআই মডেলগুলিকে ব্যবহার করতে হয়, যা শক্তিশালী ইন-ডাটাবেস রূপান্তর এবং ভবিষ্যদ্বাণী সক্ষম করে, আমাদের ব্যাংকিং অ্যাপ্লিকেশনটিকে বাজেট ট্র্যাকিং এবং অসঙ্গতি সনাক্তকরণের মতো ব্যবহারের ক্ষেত্রে স্বয়ংক্রিয়ভাবে লেনদেনগুলিকে শ্রেণীবদ্ধ করতে দেয়।
- পূর্ণ-পাঠ্য অনুসন্ধান : স্প্যানারের মধ্যে পূর্ণ-পাঠ্য অনুসন্ধান কার্যকারিতা কীভাবে বাস্তবায়ন করবেন তা শিখুন। আপনি আপনার কার্যক্ষম ডেটা জুড়ে কীওয়ার্ড-ভিত্তিক অনুসন্ধান সম্পাদনের জন্য পাঠ্য ডেটা সূচীকরণ এবং দক্ষ কোয়েরি লেখার অন্বেষণ করবেন, যা শক্তিশালী ডেটা আবিষ্কার সক্ষম করবে, যেমন আমাদের ব্যাংকিং সিস্টেমের মধ্যে ইমেল ঠিকানার মাধ্যমে দক্ষতার সাথে গ্রাহকদের খুঁজে বের করা।
- BigQuery ফেডারেটেড কোয়েরি : BigQuery-তে থাকা ডেটা সরাসরি কোয়েরি করার জন্য Spanner-এর ফেডারেটেড কোয়েরি ক্ষমতা কীভাবে কাজে লাগানো যায় তা অন্বেষণ করুন। এটি আপনাকে Spanner-এর রিয়েল-টাইম অপারেশনাল ডেটাকে BigQuery-এর বিশ্লেষণাত্মক ডেটাসেটের সাথে একত্রিত করতে দেয় যাতে ডেটা ডুপ্লিকেশন বা জটিল ETL প্রক্রিয়া ছাড়াই ব্যাপক অন্তর্দৃষ্টি এবং রিপোর্টিং করা যায়, যা আমাদের ব্যাংকিং অ্যাপ্লিকেশনে বিভিন্ন ব্যবহারের ক্ষেত্রে শক্তি যোগায় যেমন BigQuery-এর বৃহত্তর ঐতিহাসিক প্রবণতার সাথে রিয়েল-টাইম গ্রাহক ডেটা একত্রিত করে লক্ষ্যযুক্ত মার্কেটিং প্রচারণা।
তুমি কি শিখবে
- কিভাবে একটি স্প্যানার ইন্সট্যান্স সেটআপ করবেন।
- কিভাবে একটি ডাটাবেস এবং টেবিল তৈরি করবেন।
- আপনার স্প্যানার ডাটাবেস টেবিলে ডেটা কীভাবে লোড করবেন।
- স্প্যানার থেকে ভার্টেক্স এআই মডেলগুলিকে কীভাবে কল করবেন।
- ফাজি সার্চ এবং ফুল-টেক্সট সার্চ ব্যবহার করে আপনার স্প্যানার ডাটাবেস কীভাবে কোয়েরি করবেন।
- BigQuery থেকে Spanner-এর বিরুদ্ধে ফেডারেটেড কোয়েরি কীভাবে সম্পাদন করবেন।
- আপনার স্প্যানার ইন্সট্যান্সটি কীভাবে মুছে ফেলবেন।
তোমার যা লাগবে
- একটি Google ক্লাউড প্রকল্প যা একটি বিলিং অ্যাকাউন্টের সাথে সংযুক্ত।
- একটি ওয়েব ব্রাউজার, যেমন ক্রোম বা ফায়ারফক্স ।
2. সেটআপ এবং প্রয়োজনীয়তা
একটি প্রকল্প তৈরি করুন
যদি আপনার ইতিমধ্যেই বিলিং সক্ষম করে একটি গুগল ক্লাউড প্রকল্প থাকে, তাহলে কনসোলের উপরের বাম দিকে প্রকল্প নির্বাচন পুল ডাউন মেনুতে ক্লিক করুন:

একটি নির্বাচিত প্রকল্পের সাথে, প্রয়োজনীয় API গুলি সক্ষম করুন এ যান।
যদি আপনার ইতিমধ্যেই একটি Google অ্যাকাউন্ট (Gmail বা Google Apps) না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে। Google Cloud Platform কনসোলে ( console.cloud.google.com ) সাইন-ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন।
একটি নতুন প্রকল্প তৈরি করতে ফলাফল সংলাপে "নতুন প্রকল্প" বোতামে ক্লিক করুন:

যদি আপনার ইতিমধ্যেই কোন প্রকল্প না থাকে, তাহলে আপনার প্রথমটি তৈরি করার জন্য আপনার এইরকম একটি ডায়ালগ দেখতে হবে:

পরবর্তী প্রকল্প তৈরির ডায়ালগ আপনাকে আপনার নতুন প্রকল্পের বিশদ বিবরণ লিখতে দেয়।
প্রোজেক্ট আইডি মনে রাখবেন, যা সমস্ত গুগল ক্লাউড প্রোজেক্টের জন্য একটি অনন্য নাম। এই কোডল্যাবে পরে এটিকে PROJECT_ID হিসাবে উল্লেখ করা হবে।

এরপর, যদি আপনি ইতিমধ্যেই এটি না করে থাকেন, তাহলে Google ক্লাউড রিসোর্স ব্যবহার করার জন্য এবং Spanner API , Vertex AI API , BigQuery API , এবং BigQuery Connection API সক্ষম করার জন্য আপনাকে Developers Console-এ বিলিং সক্ষম করতে হবে।

স্প্যানার মূল্য নির্ধারণ এখানে নথিভুক্ত করা হয়েছে। অন্যান্য সম্পদের সাথে সম্পর্কিত অন্যান্য খরচ তাদের নির্দিষ্ট মূল্য পৃষ্ঠাগুলিতে নথিভুক্ত করা হবে।
গুগল ক্লাউড প্ল্যাটফর্মের নতুন ব্যবহারকারীরা $300 এর বিনামূল্যে ট্রায়ালের জন্য যোগ্য।
গুগল ক্লাউড শেল সেটআপ
এই কোডল্যাবে আমরা গুগল ক্লাউড শেল ব্যবহার করব, যা ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।
এই ডেবিয়ান-ভিত্তিক ভার্চুয়াল মেশিনটি আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুল দিয়ে পূর্ণ। এটি একটি স্থায়ী 5 জিবি হোম ডিরেক্টরি অফার করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এর অর্থ হল এই কোডল্যাবের জন্য আপনার যা প্রয়োজন তা হল একটি ব্রাউজার।
ক্লাউড কনসোল থেকে ক্লাউড শেল সক্রিয় করতে, কেবল ক্লাউড শেল সক্রিয় করুন ক্লিক করুন
(পরিবেশের সাথে সংযোগ স্থাপন এবং সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে)।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি ইতিমধ্যেই প্রমাণিত এবং প্রকল্পটি ইতিমধ্যেই আপনার PROJECT_ID এ সেট করা আছে।
gcloud auth list
প্রত্যাশিত আউটপুট:
Credentialed Accounts ACTIVE: * ACCOUNT: <myaccount>@<mydomain>.com
gcloud config list project
প্রত্যাশিত আউটপুট:
[core] project = <PROJECT_ID>
যদি, কোন কারণে, প্রকল্পটি সেট না করা হয়, তাহলে নিম্নলিখিত কমান্ডটি জারি করুন:
gcloud config set project <PROJECT_ID>
আপনার PROJECT_ID খুঁজছেন? সেটআপ ধাপে আপনি কোন আইডি ব্যবহার করেছেন তা দেখুন অথবা ক্লাউড কনসোল ড্যাশবোর্ডে এটি দেখুন:

ক্লাউড শেল ডিফল্টরূপে কিছু পরিবেশ ভেরিয়েবল সেট করে, যা ভবিষ্যতের কমান্ড চালানোর সময় কার্যকর হতে পারে।
echo $GOOGLE_CLOUD_PROJECT
প্রত্যাশিত আউটপুট:
<PROJECT_ID>
প্রয়োজনীয় API গুলি সক্ষম করুন
আপনার প্রকল্পের জন্য Spanner, Vertex AI, এবং BigQuery API গুলি সক্ষম করুন:
gcloud services enable spanner.googleapis.com
gcloud services enable aiplatform.googleapis.com
gcloud services enable bigquery.googleapis.com
gcloud services enable bigqueryconnection.googleapis.com
সারাংশ
এই ধাপে, যদি আপনার ইতিমধ্যেই একটি প্রকল্প না থাকে, তাহলে আপনি সেট আপ করেছেন, ক্লাউড শেল সক্রিয় করেছেন এবং প্রয়োজনীয় API গুলি সক্রিয় করেছেন।
পরবর্তী
এরপর, আপনি স্প্যানার ইনস্ট্যান্স সেট আপ করবেন।
৩. একটি স্প্যানার ইনস্ট্যান্স সেটআপ করুন
স্প্যানার ইনস্ট্যান্স তৈরি করুন
এই ধাপে, আপনি কোডল্যাবের জন্য একটি স্প্যানার ইন্সট্যান্স সেট আপ করবেন। এটি করার জন্য, ক্লাউড শেল খুলুন এবং এই কমান্ডটি চালান:
export SPANNER_INSTANCE=cloudspanner-onlinebanking
gcloud spanner instances create $SPANNER_INSTANCE \
--config=regional-us-central1 \
--description="Spanner Online Banking" \
--nodes=1 \
--edition=ENTERPRISE \
--default-backup-schedule-type=NONE
প্রত্যাশিত আউটপুট:
Creating instance...done.
সারাংশ
এই ধাপে, আপনি স্প্যানার ইনস্ট্যান্স তৈরি করেছেন।
পরবর্তী
এরপর, আপনি প্রাথমিক অ্যাপ্লিকেশন প্রস্তুত করবেন এবং ডাটাবেস এবং স্কিমা তৈরি করবেন।
৪. একটি ডাটাবেস এবং স্কিমা তৈরি করুন
প্রাথমিক আবেদনপত্র প্রস্তুত করুন
এই ধাপে, আপনি কোডের মাধ্যমে ডাটাবেস এবং স্কিমা তৈরি করবেন।
প্রথমে, Maven ব্যবহার করে onlinebanking নামে একটি জাভা অ্যাপ্লিকেশন তৈরি করুন:
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.google.codelabs \
-DartifactId=onlinebanking \
-DjavaCompilerVersion=1.8 \
-DjunitVersion=4.13.2 \
-DarchetypeVersion=1.5
আমরা ডাটাবেসে যে ডেটা ফাইলগুলি যোগ করব তা চেকআউট করুন এবং কপি করুন (কোড রিপোজিটরির জন্য এখানে দেখুন):
git clone https://github.com/GoogleCloudPlatform/cloud-spanner-samples.git
cp -r ./cloud-spanner-samples/banking/data ./onlinebanking
অ্যাপ্লিকেশন ফোল্ডারে নেভিগেট করুন:
cd onlinebanking
Maven pom.xml ফাইলটি খুলুন। Google Cloud লাইব্রেরির সংস্করণ পরিচালনা করতে Maven BOM ব্যবহার করতে নির্ভরতা ব্যবস্থাপনা বিভাগটি যোগ করুন:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.56.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
এডিটর এবং ফাইলটি দেখতে এরকম হবে: 
অ্যাপ্লিকেশনটি যে লাইব্রেরিগুলি ব্যবহার করবে তা dependencies বিভাগে অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করুন:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.10</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bigquery</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bigqueryconnection</artifactId>
</dependency>
</dependencies>
অবশেষে, বিল্ড প্লাগইনগুলি প্রতিস্থাপন করুন যাতে অ্যাপ্লিকেশনটি একটি রানযোগ্য JAR-তে প্যাকেজ করা হয়:
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.artifactId}-resources</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.artifactId}-resources/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<outputDirectory>${project.build.directory}</outputDirectory>
<archive>
<index>false</index>
<manifest>
<mainClass>com.google.codelabs.App</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>${project.artifactId}-resources/lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
ক্লাউড শেল এডিটরের "ফাইল" মেনুর অধীনে "সংরক্ষণ করুন" নির্বাচন করে অথবা Ctrl+S টিপে pom.xml ফাইলে করা পরিবর্তনগুলি সংরক্ষণ করুন।
এখন যেহেতু নির্ভরতাগুলি প্রস্তুত, আপনি অ্যাপে কোড যুক্ত করে একটি স্কিমা, কিছু সূচক (অনুসন্ধান সহ) এবং একটি দূরবর্তী শেষ বিন্দুর সাথে সংযুক্ত একটি AI মডেল তৈরি করবেন। আপনি এই শিল্পকর্মগুলি তৈরি করবেন এবং এই কোডল্যাব বরাবর এই ক্লাসে আরও পদ্ধতি যুক্ত করবেন।
onlinebanking/src/main/java/com/google/codelabs এর অধীনে App.java খুলুন এবং কন্টেন্টগুলি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:
package com.google.codelabs;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
public class App {
// Create the Spanner database and schema
public static void create(DatabaseAdminClient dbAdminClient, DatabaseId db,
String location, String model) {
System.out.println("Creating Spanner database...");
List<String> statements = Arrays.asList(
"CREATE TABLE Customers (\n"
+ " CustomerId INT64 NOT NULL,\n"
+ " FirstName STRING(256) NOT NULL,\n"
+ " LastName STRING(256) NOT NULL,\n"
+ " FullName STRING(512) AS (FirstName || ' ' || LastName) STORED,\n"
+ " Email STRING(512) NOT NULL,\n"
+ " EmailTokens TOKENLIST AS\n"
+ " (TOKENIZE_SUBSTRING(Email, ngram_size_min=>2, ngram_size_max=>3,\n"
+ " relative_search_types=>[\"all\"])) HIDDEN,\n"
+ " Address STRING(MAX)\n"
+ ") PRIMARY KEY (CustomerId)",
"CREATE INDEX CustomersByEmail\n"
+ "ON Customers(Email)",
"CREATE SEARCH INDEX CustomersFuzzyEmail\n"
+ "ON Customers(EmailTokens)",
"CREATE TABLE Accounts (\n"
+ " AccountId INT64 NOT NULL,\n"
+ " CustomerId INT64 NOT NULL,\n"
+ " AccountType STRING(256) NOT NULL,\n"
+ " Balance NUMERIC NOT NULL,\n"
+ " OpenDate TIMESTAMP NOT NULL\n"
+ ") PRIMARY KEY (AccountId)",
"CREATE INDEX AccountsByCustomer\n"
+ "ON Accounts (CustomerId)",
"CREATE TABLE TransactionLedger (\n"
+ " TransactionId INT64 NOT NULL,\n"
+ " AccountId INT64 NOT NULL,\n"
+ " TransactionType STRING(256) NOT NULL,\n"
+ " Amount NUMERIC NOT NULL,\n"
+ " Timestamp TIMESTAMP NOT NULL"
+ " OPTIONS(allow_commit_timestamp=true),\n"
+ " Category STRING(256),\n"
+ " Description STRING(MAX),\n"
+ " CategoryTokens TOKENLIST AS (TOKENIZE_FULLTEXT(Category)) HIDDEN,\n"
+ " DescriptionTokens TOKENLIST AS (TOKENIZE_FULLTEXT(Description)) HIDDEN\n"
+ ") PRIMARY KEY (AccountId, TransactionId),\n"
+ "INTERLEAVE IN PARENT Accounts ON DELETE CASCADE",
"CREATE INDEX TransactionLedgerByAccountType\n"
+ "ON TransactionLedger(AccountId, TransactionType)",
"CREATE INDEX TransactionLedgerByCategory\n"
+ "ON TransactionLedger(AccountId, Category)",
"CREATE SEARCH INDEX TransactionLedgerTextSearch\n"
+ "ON TransactionLedger(CategoryTokens, DescriptionTokens)",
"CREATE MODEL TransactionCategoryModel\n"
+ "INPUT (prompt STRING(MAX))\n"
+ "OUTPUT (content STRING(MAX))\n"
+ "REMOTE OPTIONS (\n"
+ " endpoint = '//aiplatform.googleapis.com/projects/" + db.getInstanceId().getProject()
+ "/locations/" + location + "/publishers/google/models/" + model + "',\n"
+ " default_batch_size = 1\n"
+ ")");
OperationFuture<Database, CreateDatabaseMetadata> op = dbAdminClient.createDatabase(
db.getInstanceId().getInstance(),
db.getDatabase(),
statements);
try {
Database dbOperation = op.get();
System.out.println("Created Spanner database [" + dbOperation.getId() + "]");
} catch (ExecutionException e) {
throw (SpannerException) e.getCause();
} catch (InterruptedException e) {
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
static void printUsageAndExit() {
System.out.println("Online Online Banking Application 1.0.0");
System.out.println("Usage:");
System.out.println(" java -jar target/onlinebanking.jar <command> [command_option(s)]");
System.out.println("");
System.out.println("Examples:");
System.out.println(" java -jar target/onlinebanking.jar create");
System.out.println(" - Create a sample Spanner database and schema in your "
+ "project.\n");
System.exit(1);
}
public static void main(String[] args) {
if (args.length < 1) {
printUsageAndExit();
}
String instanceId = System.getProperty("SPANNER_INSTANCE", System.getenv("SPANNER_INSTANCE"));
String databaseId = System.getProperty("SPANNER_DATABASE", System.getenv("SPANNER_DATABASE"));
String location = System.getenv().getOrDefault("SPANNER_LOCATION", "us-central1");
String model = System.getenv().getOrDefault("SPANNER_MODEL", "gemini-2.0-flash-lite");
if (instanceId == null || databaseId == null) {
System.err.println("Missing one or more required environment variables: SPANNER_INSTANCE or "
+ "SPANNER_DATABASE");
System.exit(1);
}
BigQueryOptions bigqueryOptions = BigQueryOptions.newBuilder().build();
BigQuery bigquery = bigqueryOptions.getService();
SpannerOptions spannerOptions = SpannerOptions.newBuilder().build();
try (Spanner spanner = spannerOptions.getService()) {
String command = args[0];
DatabaseId db = DatabaseId.of(spannerOptions.getProjectId(), instanceId, databaseId);
DatabaseClient dbClient = spanner.getDatabaseClient(db);
DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
switch (command) {
case "create":
create(dbAdminClient, db, location, model);
break;
default:
printUsageAndExit();
}
}
}
}
পরিবর্তনগুলি App.java তে সংরক্ষণ করুন।
আপনার কোড তৈরি করছে এমন বিভিন্ন সত্তাগুলি একবার দেখুন এবং JAR অ্যাপ্লিকেশনটি তৈরি করুন:
mvn package
প্রত্যাশিত আউটপুট:
[INFO] Building jar: /home/your_user/onlinebanking/target/onlinebanking.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
ব্যবহারের তথ্য দেখতে অ্যাপ্লিকেশনটি চালান:
java -jar target/onlinebanking.jar
প্রত্যাশিত আউটপুট:
Online Banking Application 1.0.0
Usage:
java -jar target/onlinebanking.jar <command> [command_option(s)]
Examples:
java -jar target/onlinebanking.jar create
- Create a sample Spanner database and schema in your project.
ডাটাবেস এবং স্কিমা তৈরি করুন
প্রয়োজনীয় অ্যাপ্লিকেশন পরিবেশ ভেরিয়েবল সেট করুন:
export SPANNER_INSTANCE=cloudspanner-onlinebanking
export SPANNER_DATABASE=onlinebanking
create কমান্ডটি চালিয়ে ডাটাবেস এবং স্কিমা তৈরি করুন:
java -jar target/onlinebanking.jar create
প্রত্যাশিত আউটপুট:
Creating Spanner database... Created Spanner database [<DATABASE_RESOURCE_NAME>]
স্প্যানারে স্কিমা পরীক্ষা করুন
স্প্যানার কনসোলে , আপনার তৈরি করা ইনস্ট্যান্স এবং ডাটাবেসে নেভিগেট করুন।
আপনার তিনটি টেবিলই দেখা উচিত - Accounts , Customers এবং TransactionLedger ।

এই ক্রিয়াটি ডাটাবেস স্কিমা তৈরি করে, যার মধ্যে রয়েছে Accounts , Customers এবং TransactionLedger টেবিল, অপ্টিমাইজড ডেটা পুনরুদ্ধারের জন্য সেকেন্ডারি ইনডেক্স এবং একটি ভার্টেক্স এআই মডেল রেফারেন্স।

উন্নত ডেটা লোকালটির মাধ্যমে অ্যাকাউন্ট-নির্দিষ্ট লেনদেনের জন্য ক্যোয়ারী কর্মক্ষমতা উন্নত করার জন্য TransactionLedger টেবিলটি অ্যাকাউন্টগুলির মধ্যে আন্তঃলিভ করা হয়েছে।
এই কোডল্যাবে ব্যবহৃত সাধারণ ডেটা অ্যাক্সেস প্যাটার্নগুলিকে অপ্টিমাইজ করার জন্য সেকেন্ডারি ইনডেক্সগুলি ( CustomersByEmail , CustomersFuzzyEmail , AccountsByCustomer , TransactionLedgerByAccountType , TransactionLedgerByCategory , TransactionLedgerTextSearch ) প্রয়োগ করা হয়েছিল, যেমন সঠিক এবং অস্পষ্ট ইমেল দ্বারা গ্রাহক অনুসন্ধান, গ্রাহক দ্বারা অ্যাকাউন্ট পুনরুদ্ধার এবং দক্ষতার সাথে লেনদেনের ডেটা অনুসন্ধান এবং অনুসন্ধান করা।
TransactionCategoryModel Vertex AI ব্যবহার করে LLM-এ সরাসরি SQL কল সক্ষম করে, যা এই কোডল্যাবে গতিশীল লেনদেন শ্রেণীবদ্ধকরণের জন্য ব্যবহৃত হয়।
সারাংশ
এই ধাপে, আপনি স্প্যানার ডাটাবেস এবং স্কিমা তৈরি করেছেন।
পরবর্তী
এরপর, আপনি নমুনা অ্যাপ্লিকেশন ডেটা লোড করবেন।
৫. ডেটা লোড করুন
এখন, আপনি CSV ফাইল থেকে নমুনা ডেটা ডাটাবেসে লোড করার জন্য কার্যকারিতা যোগ করবেন।
App.java খুলুন এবং আমদানিগুলি প্রতিস্থাপন করে শুরু করুন:
package com.google.codelabs;
import java.io.FileReader;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.Timestamp;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Key;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Struct;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
import com.opencsv.CSVReader;
তারপর ক্লাস App insert পদ্ধতিগুলি যোগ করুন:
// Insert customers from CSV
public static void insertCustomers(DatabaseClient dbClient) {
System.out.println("Inserting customers...");
dbClient
.readWriteTransaction()
.run(transaction -> {
int count = 0;
List<Statement> statements = new ArrayList<>();
try (CSVReader reader = new CSVReader(new FileReader("data/customers.csv"))) {
reader.skip(1);
String[] line;
while ((line = reader.readNext()) != null) {
Statement statement = Statement.newBuilder(
"INSERT INTO Customers (CustomerId, FirstName, LastName, Email, Address) "
+ "VALUES (@customerId, @firstName, @lastName, @email, @address)")
.bind("customerId").to(Long.parseLong(line[0]))
.bind("firstName").to(line[1])
.bind("lastName").to(line[2])
.bind("email").to(line[3])
.bind("address").to(line[4])
.build();
statements.add(statement);
count++;
}
transaction.batchUpdate(statements);
System.out.println("Inserted " + count + " customers");
return null;
}
});
}
// Insert accounts from CSV
public static void insertAccounts(DatabaseClient dbClient) {
System.out.println("Inserting accounts...");
dbClient
.readWriteTransaction()
.run(transaction -> {
int count = 0;
List<Statement> statements = new ArrayList<>();
try (CSVReader reader = new CSVReader(new FileReader("data/accounts.csv"))) {
reader.skip(1);
String[] line;
while ((line = reader.readNext()) != null) {
Statement statement = Statement.newBuilder(
"INSERT INTO Accounts (AccountId, CustomerId, AccountType, Balance, OpenDate) "
+ "VALUES (@accountId, @customerId, @accountType, @balance, @openDate)")
.bind("accountId").to(Long.parseLong(line[0]))
.bind("customerId").to(Long.parseLong(line[1]))
.bind("accountType").to(line[2])
.bind("balance").to(new BigDecimal(line[3]))
.bind("openDate").to(line[4])
.build();
statements.add(statement);
count++;
}
transaction.batchUpdate(statements);
System.out.println("Inserted " + count + " accounts");
return null;
}
});
}
// Insert transactions from CSV
public static void insertTransactions(DatabaseClient dbClient) {
System.out.println("Inserting transactions...");
dbClient
.readWriteTransaction()
.run(transaction -> {
int count = 0;
List<Statement> statements = new ArrayList<>();
try (CSVReader reader = new CSVReader(new FileReader("data/transactions.csv"))) {
reader.skip(1);
String[] line;
// Specify timestamps that are within last 30 days
Random random = new Random();
Instant startTime = Instant.now().minus(15, ChronoUnit.DAYS);
Instant currentTimestamp = startTime;
Map<Long, BigDecimal> balanceChanges = new HashMap<>();
while ((line = reader.readNext()) != null) {
long accountId = Long.parseLong(line[1]);
String transactionType = line[2];
BigDecimal amount = new BigDecimal(line[3]);
int randomMinutes = random.nextInt(60) + 1;
currentTimestamp = currentTimestamp.plus(Duration.ofMinutes(randomMinutes));
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(
currentTimestamp.getEpochSecond(), currentTimestamp.getNano());
Statement statement = Statement.newBuilder(
"INSERT INTO TransactionLedger (TransactionId, AccountId, TransactionType, Amount,"
+ "Timestamp, Category, Description) "
+ "VALUES (@transactionId, @accountId, @transactionType, @amount, @timestamp,"
+ "@category, @description)")
.bind("transactionId").to(Long.parseLong(line[0]))
.bind("accountId").to(accountId)
.bind("transactionType").to(transactionType)
.bind("amount").to(amount)
.bind("timestamp").to(timestamp)
.bind("category").to(line[5])
.bind("description").to(line[6])
.build();
statements.add(statement);
// Track balance changes per account
BigDecimal balanceChange = balanceChanges.getOrDefault(accountId,
BigDecimal.ZERO);
if ("Credit".equalsIgnoreCase(transactionType)) {
balanceChanges.put(accountId, balanceChange.add(amount));
} else if ("Debit".equalsIgnoreCase(transactionType)) {
balanceChanges.put(accountId, balanceChange.subtract(amount));
} else {
System.err.println("Unsupported transaction type: " + transactionType);
continue;
}
count++;
}
// Apply final balance updates
for (Map.Entry<Long, BigDecimal> entry : balanceChanges.entrySet()) {
long accountId = entry.getKey();
BigDecimal balanceChange = entry.getValue();
Struct row = transaction.readRow(
"Accounts",
Key.of(accountId),
List.of("Balance"));
if (row != null) {
BigDecimal currentBalance = row.getBigDecimal("Balance");
BigDecimal updatedBalance = currentBalance.add(balanceChange);
Statement statement = Statement.newBuilder(
"UPDATE Accounts SET Balance = @balance WHERE AccountId = @accountId")
.bind("accountId").to(accountId)
.bind("balance").to(updatedBalance)
.build();
statements.add(statement);
}
}
transaction.batchUpdate(statements);
System.out.println("Inserted " + count + " transactions");
}
return null;
});
}
switch (command) এর জন্য main পদ্ধতিতে আরেকটি কেস স্টেটমেন্ট যোগ করুন:
case "insert":
String insertType = (args.length >= 2) ? args[1] : "";
if (insertType.equals("customers")) {
insertCustomers(dbClient);
} else if (insertType.equals("accounts")) {
insertAccounts(dbClient);
} else if (insertType.equals("transactions")) {
insertTransactions(dbClient);
} else {
insertCustomers(dbClient);
insertAccounts(dbClient);
insertTransactions(dbClient);
}
break;
অবশেষে, printUsageAndExit পদ্ধতিতে insert কীভাবে ব্যবহার করবেন তা সংযুক্ত করুন:
System.out.println(" java -jar target/onlinebanking.jar insert");
System.out.println(" - Insert sample Customers, Accounts, and Transactions into the "
+ "database.\n");
আপনার করা পরিবর্তনগুলি App.java তে সংরক্ষণ করুন।
অ্যাপ্লিকেশনটি পুনর্নির্মাণ করুন:
mvn package
insert কমান্ডটি চালিয়ে নমুনা ডেটা সন্নিবেশ করান:
java -jar target/onlinebanking.jar insert
প্রত্যাশিত আউটপুট:
Inserting customers... Inserted 100 customers Inserting accounts... Inserted 125 accounts Inserting transactions... Inserted 200 transactions
স্প্যানার কনসোলে , আপনার ইনস্ট্যান্স এবং ডাটাবেসের জন্য স্প্যানার স্টুডিওতে ফিরে যান। তারপর TransactionLedger টেবিলটি নির্বাচন করুন এবং ডেটা লোড হয়েছে কিনা তা যাচাই করতে সাইডবারে "ডেটা" এ ক্লিক করুন। টেবিলে 200টি সারি থাকা উচিত।

সারাংশ
এই ধাপে, আপনি ডাটাবেসে নমুনা ডেটা সন্নিবেশ করেছেন।
পরবর্তী
এরপর, আপনি স্প্যানার এসকিউএল-এর মধ্যে সরাসরি ব্যাংকিং লেনদেনগুলিকে স্বয়ংক্রিয়ভাবে শ্রেণীবদ্ধ করতে ভার্টেক্স এআই ইন্টিগ্রেশন ব্যবহার করবেন।
৬. ভার্টেক্স এআই দিয়ে ডেটা শ্রেণীবদ্ধ করুন
এই ধাপে, আপনি Vertex AI এর ক্ষমতা ব্যবহার করে আপনার আর্থিক লেনদেনগুলিকে সরাসরি Spanner SQL এর মধ্যে শ্রেণীবদ্ধ করতে পারবেন। Vertex AI এর মাধ্যমে আপনি একটি বিদ্যমান প্রশিক্ষিত মডেল বেছে নিতে পারেন অথবা আপনার নিজস্ব মডেল তৈরি করতে পারেন। Vertex AI মডেল গার্ডেনে উপলব্ধ মডেলগুলি দেখুন।
এই কোডল্যাবের জন্য আমরা জেমিনি মডেলগুলির মধ্যে একটি, Gemini Flash Lite ব্যবহার করব। জেমিনির এই সংস্করণটি সাশ্রয়ী হলেও বেশিরভাগ দৈনন্দিন কাজের চাপ সামলাতে পারে।
বর্তমানে, আমাদের কাছে বেশ কিছু আর্থিক লেনদেন আছে যা আমরা বর্ণনার উপর নির্ভর করে শ্রেণীবদ্ধ করতে চাই ( groceries , transportation , ইত্যাদি)। আমরা স্প্যানারে একটি মডেল নিবন্ধন করে এবং তারপর ML.PREDICT ব্যবহার করে AI মডেলটি কল করে এটি করতে পারি।
আমাদের ব্যাংকিং অ্যাপ্লিকেশনে আমরা গ্রাহকের আচরণ সম্পর্কে আরও গভীর অন্তর্দৃষ্টি অর্জনের জন্য লেনদেনগুলিকে শ্রেণীবদ্ধ করতে চাইতে পারি যাতে আমরা পরিষেবাগুলিকে ব্যক্তিগতকৃত করতে পারি, অসঙ্গতিগুলি আরও কার্যকরভাবে সনাক্ত করতে পারি, অথবা গ্রাহককে মাসিক বাজেট ট্র্যাক করার ক্ষমতা প্রদান করতে পারি।
আমরা যখন ডাটাবেস এবং স্কিমা তৈরি করেছিলাম তখন প্রথম ধাপটি ইতিমধ্যেই সম্পন্ন হয়েছিল, যা এই ধরণের একটি মডেল তৈরি করেছিল:

এরপর, আমরা অ্যাপ্লিকেশনটিতে ML.PREDICT কল করার জন্য একটি পদ্ধতি যুক্ত করব।
App.java খুলুন এবং categorize পদ্ধতি যোগ করুন:
// Use Vertex AI to set the category of transactions
public static void categorize(DatabaseClient dbClient) {
System.out.println("Categorizing transactions...");
try {
// Create a prompt to instruct the LLM how to categorize the transactions
String categories = String.join(", ", Arrays.asList("Entertainment", "Gifts", "Groceries",
"Investment", "Medical", "Movies", "Online Shopping", "Other", "Purchases", "Refund",
"Restaurants", "Salary", "Transfer", "Transportation", "Utilities"));
String prompt = "Categorize the following financial activity into one of these "
+ "categories: " + categories + ". Return Other if the description cannot be mapped to "
+ "one of these categories. Only return the exact category string, no other text or "
+ "punctuation or reasoning. Description: ";
String sql = "UPDATE TransactionLedger SET Category = (\n"
+ " SELECT content FROM ML.PREDICT(MODEL `TransactionCategoryModel`, (\n"
+ " SELECT CONCAT('" + prompt + "', CASE WHEN TRIM(Description) = ''\n"
+ " THEN 'Other' ELSE Description END) AS prompt\n"
+ " ))\n"
+ ") WHERE TRUE";
// Use partitioned update to batch update a large number of rows
dbClient.executePartitionedUpdate(Statement.of(sql));
System.out.println("Completed categorizing transactions");
} catch (SpannerException e) {
throw e;
}
}
শ্রেণীবদ্ধ করার জন্য main পদ্ধতিতে আরেকটি কেস স্টেটমেন্ট যোগ করুন:
case "categorize":
categorize(dbClient);
break;
অবশেষে, printUsageAndExit পদ্ধতিতে categorize কীভাবে ব্যবহার করবেন তা সংযুক্ত করুন:
System.out.println(" java -jar target/onlinebanking.jar categorize");
System.out.println(" - Use AI to categorize transactions in the database.\n");
আপনার করা পরিবর্তনগুলি App.java তে সংরক্ষণ করুন।
অ্যাপ্লিকেশনটি পুনর্নির্মাণ করুন:
mvn package
categorize কমান্ডটি ব্যবহার করে ডাটাবেসে লেনদেনগুলিকে শ্রেণীবদ্ধ করুন:
java -jar target/onlinebanking.jar categorize
প্রত্যাশিত আউটপুট:
Categorizing transactions... Completed categorizing transactions
স্প্যানার স্টুডিওতে, TransactionLedger টেবিলের জন্য Preview Data স্টেটমেন্টটি চালান। এখন সমস্ত সারির জন্য Category কলামটি পূরণ করা উচিত।

এখন যেহেতু আমরা লেনদেনগুলিকে শ্রেণীবদ্ধ করেছি, আমরা অভ্যন্তরীণ বা গ্রাহক-মুখী প্রশ্নের জন্য এই তথ্য ব্যবহার করতে পারি, পরবর্তী ধাপে আমরা দেখব কিভাবে একজন গ্রাহক মাসে কোন বিভাগে কত খরচ করছেন তা খুঁজে বের করা যায়।
সারাংশ
এই ধাপে, আপনি আপনার ডেটার AI-চালিত শ্রেণীবিভাগ সম্পাদনের জন্য একটি পূর্ব-প্রশিক্ষিত মডেল ব্যবহার করেছেন।
পরবর্তী
এরপর, আপনি অস্পষ্ট এবং পূর্ণ-পাঠ্য অনুসন্ধান সম্পাদনের জন্য টোকেনাইজেশন ব্যবহার করবেন।
৭. পূর্ণ-পাঠ্য অনুসন্ধান ব্যবহার করে অনুসন্ধান করুন
কোয়েরি কোড যোগ করুন
স্প্যানার অনেক পূর্ণ-পাঠ্য অনুসন্ধান কোয়েরি প্রদান করে। এই ধাপে আপনি একটি সঠিক-মিল অনুসন্ধান করবেন, তারপর একটি অস্পষ্ট অনুসন্ধান এবং একটি পূর্ণ-পাঠ্য অনুসন্ধান করবেন।
App.java খুলুন এবং আমদানিগুলি প্রতিস্থাপন করে শুরু করুন:
package com.google.codelabs;
import java.io.FileReader;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.Timestamp;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Key;
import com.google.cloud.spanner.ReadOnlyTransaction;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.TimestampBound;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
import com.opencsv.CSVReader;
তারপর কোয়েরি পদ্ধতিগুলি যোগ করুন:
// Get current account balance(s) by customer
public static void getBalance(DatabaseClient dbClient, long customerId) {
String query = "SELECT AccountId, Balance\n"
+ "FROM Accounts\n"
+ "WHERE CustomerId = @customerId";
Statement statement = Statement.newBuilder(query)
.bind("customerId").to(customerId)
.build();
// Ignore ongoing transactions, use stale reads as seconds-old data is sufficient
TimestampBound stalenessBound = TimestampBound.ofMaxStaleness(5, TimeUnit.SECONDS);
try (ReadOnlyTransaction transaction = dbClient.singleUseReadOnlyTransaction(stalenessBound);
ResultSet resultSet = transaction.executeQuery(statement);) {
System.out.println("Account balances for customer " + customerId + ":");
while (resultSet.next()) {
System.out.println(" Account " + resultSet.getLong("AccountId") + ": "
+ resultSet.getBigDecimal("Balance"));
}
}
}
// Find customers by email
public static void findCustomers(DatabaseClient dbClient, String email) {
// Query using fuzzy search (ngrams) to allow for spelling mistakes
String query = "SELECT CustomerId, Email\n"
+ "FROM Customers\n"
+ "WHERE SEARCH_NGRAMS(EmailTokens, @email)\n"
+ "ORDER BY SCORE_NGRAMS(EmailTokens, @email) DESC\n"
+ "LIMIT 10";
Statement statement = Statement.newBuilder(query)
.bind("email").to(email)
.build();
try (ReadOnlyTransaction transaction = dbClient.singleUseReadOnlyTransaction();
ResultSet resultSet = transaction.executeQuery(statement)) {
System.out.println("Customer emails matching " + email + " (top 10 matches):");
while (resultSet.next()) {
System.out.println(" Customer " + resultSet.getLong("CustomerId") + ": "
+ resultSet.getString("Email"));
}
}
}
// Get total monthly spending for a customer by category
public static void getSpending(DatabaseClient dbClient, long customerId, String category) {
// Query category using full-text search
String query = "SELECT SUM(Amount) as TotalSpending\n"
+ "FROM TransactionLedger t\n"
+ "JOIN Accounts a\n"
+ " ON t.AccountId = a.AccountId\n"
+ "WHERE t.TransactionType = 'Debit'\n"
+ " AND a.CustomerId = @customerId\n"
+ " AND t.Timestamp >= TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -30 DAY)\n"
+ " AND (SEARCH(t.CategoryTokens, @category) OR SEARCH(t.DescriptionTokens, @category))";
Statement statement = Statement.newBuilder(query)
.bind("customerId").to(customerId)
.bind("category").to(category)
.build();
try (ReadOnlyTransaction transaction = dbClient.singleUseReadOnlyTransaction();
ResultSet resultSet = transaction.executeQuery(statement);) {
System.out.println("Total spending for customer " + customerId + " under category "
+ category + ":");
while (resultSet.next()) {
BigDecimal totalSpending = BigDecimal.ZERO;
if (!resultSet.isNull("TotalSpending")) {
totalSpending = resultSet.getBigDecimal("TotalSpending");
}
System.out.println(" " + totalSpending);
}
}
}
কোয়েরির জন্য main পদ্ধতিতে আরেকটি case স্টেটমেন্ট যোগ করুন:
case "query":
String queryType = (args.length >= 2) ? args[1] : "";
if (queryType.equals("balance")) {
long customerId = (args.length >= 3) ? Long.parseLong(args[2]) : 1L;
getBalance(dbClient, customerId);
} else if (queryType.equals("email")) {
String email = (args.length >= 3) ? args[2] : "";
findCustomers(dbClient, email);
} else if (queryType.equals("spending")) {
long customerId = (args.length >= 3) ? Long.parseLong(args[2]) : 1L;
String category = (args.length >= 4) ? args[3] : "";
getSpending(dbClient, customerId, category);
} else {
printUsageAndExit();
}
break;
অবশেষে, printUsageAndExit পদ্ধতিতে কোয়েরি কমান্ডগুলি কীভাবে ব্যবহার করবেন তা সংযুক্ত করুন:
System.out.println(" java -jar target/onlinebanking.jar query balance 1");
System.out.println(" - Query customer account balance(s) by customer id.\n");
System.out.println(" java -jar target/onlinebanking.jar query email madi");
System.out.println(" - Find customers by email using fuzzy search.\n");
System.out.println(" java -jar target/onlinebanking.jar query spending 1 groceries");
System.out.println(" - Query customer spending by customer id and category using "
+ "full-text search.\n");
আপনার করা পরিবর্তনগুলি App.java তে সংরক্ষণ করুন।
অ্যাপ্লিকেশনটি পুনর্নির্মাণ করুন:
mvn package
গ্রাহক অ্যাকাউন্ট ব্যালেন্সের জন্য একটি সঠিক-মিল অনুসন্ধান করুন
একটি হুবহু মিলের কোয়েরি এমন সারিগুলির সন্ধান করে যা হুবহু একটি শব্দের সাথে মেলে।
কর্মক্ষমতা উন্নত করার জন্য, ডাটাবেস এবং স্কিমা তৈরি করার সময় একটি সূচক ইতিমধ্যেই যোগ করা হয়েছিল:
"CREATE INDEX AccountsByCustomer\n"
+ "ON Accounts (CustomerId)",
getBalance পদ্ধতিটি পরোক্ষভাবে এই সূচকটি ব্যবহার করে প্রদত্ত গ্রাহক আইডির সাথে মেলে এমন গ্রাহকদের খুঁজে বের করে এবং সেই গ্রাহকের অ্যাকাউন্টগুলিতেও যোগদান করে।
স্প্যানার স্টুডিওতে সরাসরি কার্যকর করার সময় কোয়েরিটি এইরকম দেখায়: 
নিম্নলিখিত কমান্ডটি ব্যবহার করে গ্রাহক 1 এর অ্যাকাউন্টের ব্যালেন্স তালিকাভুক্ত করুন:
java -jar target/onlinebanking.jar query balance 1
প্রত্যাশিত আউটপুট:
Account balances for customer 1: Account 1: 9875.25 Account 7: 9900 Account 110: 38200
১০০ জন গ্রাহক আছেন, তাই আপনি অন্য যেকোনো গ্রাহকের অ্যাকাউন্ট ব্যালেন্সের জন্য একটি ভিন্ন গ্রাহক আইডি উল্লেখ করে জিজ্ঞাসা করতে পারেন:
java -jar target/onlinebanking.jar query balance 5
java -jar target/onlinebanking.jar query balance 10
java -jar target/onlinebanking.jar query balance 99
গ্রাহকের ইমেলগুলির বিরুদ্ধে একটি অস্পষ্ট অনুসন্ধান করুন
অস্পষ্ট অনুসন্ধানের মাধ্যমে বানানের বৈচিত্র্য এবং টাইপোগ্রাফি সহ অনুসন্ধান পদগুলির জন্য আনুমানিক মিল খুঁজে পাওয়া সম্ভব।
ডাটাবেস এবং স্কিমা তৈরি করার সময় একটি n-গ্রাম সূচক ইতিমধ্যেই যোগ করা হয়েছিল:
CREATE TABLE Customers (
...
EmailTokens TOKENLIST AS (TOKENIZE_SUBSTRING(Email,
ngram_size_min=>2,
ngram_size_max=>3,
relative_search_types=>["all"])) HIDDEN,
) PRIMARY KEY(CustomerId);
CREATE SEARCH INDEX CustomersFuzzyEmail ON Customers(EmailTokens);
findCustomers পদ্ধতিটি ইমেলের মাধ্যমে গ্রাহকদের খুঁজে পেতে এই সূচকের বিরুদ্ধে অনুসন্ধান করতে SEARCH_NGRAMS এবং SCORE_NGRAMS ব্যবহার করে। ইমেল কলামটি n-গ্রাম টোকেনাইজ করা হয়েছে বলে এই প্রশ্নে বানান ভুল থাকতে পারে এবং তবুও একটি সঠিক উত্তর দিতে পারে। ফলাফলগুলি সেরা মিলের উপর ভিত্তি করে সাজানো হয়।
নিম্নলিখিত কমান্ডটি ব্যবহার করে madi সম্বলিত গ্রাহকের ইমেল ঠিকানাগুলি খুঁজে বের করুন:
java -jar target/onlinebanking.jar query email madi
প্রত্যাশিত আউটপুট:
Customer emails matching madi (top 10 matches): Customer 39: madison.perez@example.com Customer 64: mason.gray@example.com Customer 91: mabel.alexander@example.com
এই প্রতিক্রিয়াটি madi , অথবা অনুরূপ স্ট্রিং সহ নিকটতম মিলগুলি র্যাঙ্ক করা ক্রম অনুসারে দেখায়।
স্প্যানার স্টুডিওতে সরাসরি কার্যকর করা হলে কোয়েরিটি এরকম দেখাবে: 
emily এর ভুল বানানের মতো বানান ভুলের ক্ষেত্রেও অস্পষ্ট অনুসন্ধান সাহায্য করতে পারে।
java -jar target/onlinebanking.jar query email emily
java -jar target/onlinebanking.jar query email emliy
java -jar target/onlinebanking.jar query email emilee
প্রত্যাশিত আউটপুট:
Customer emails matching emliy (top 10 matches): Customer 31: emily.lopez@example.com
প্রতিটি ক্ষেত্রেই প্রত্যাশিত গ্রাহকের ইমেলটি সর্বোচ্চ হিট হিসেবে ফেরত পাঠানো হয়।
পূর্ণ-পাঠ্য অনুসন্ধানের মাধ্যমে লেনদেন অনুসন্ধান করুন
স্প্যানারের পূর্ণ-পাঠ্য অনুসন্ধান বৈশিষ্ট্যটি কীওয়ার্ড বা বাক্যাংশের উপর ভিত্তি করে রেকর্ড পুনরুদ্ধার করতে ব্যবহৃত হয়। এটিতে বানান ভুল সংশোধন করার বা সমার্থক শব্দ অনুসন্ধান করার ক্ষমতা রয়েছে।
ডাটাবেস এবং স্কিমা তৈরি করার সময় একটি পূর্ণ-পাঠ্য অনুসন্ধান সূচক ইতিমধ্যেই যোগ করা হয়েছিল:
CREATE TABLE TransactionLedger ( ... CategoryTokens TOKENLIST AS (TOKENIZE_FULLTEXT(Category)) HIDDEN, DescriptionTokens TOKENLIST AS (TOKENIZE_FULLTEXT(Description)) HIDDEN, ) PRIMARY KEY(AccountId, TransactionId), INTERLEAVE IN PARENT Accounts ON DELETE CASCADE; CREATE SEARCH INDEX TransactionLedgerTextSearch ON TransactionLedger(CategoryTokens, DescriptionTokens);
getSpending পদ্ধতিটি সেই সূচকের সাথে মেলানোর জন্য SEARCH পূর্ণ-পাঠ্য অনুসন্ধান ফাংশন ব্যবহার করে। এটি প্রদত্ত গ্রাহক আইডির জন্য গত 30 দিনের সমস্ত ব্যয় (ডেবিট) অনুসন্ধান করে।
নিম্নলিখিত কমান্ডটি ব্যবহার করে groceries বিভাগে গ্রাহক 1 এর গত মাসে মোট খরচের হিসাব পান:
java -jar target/onlinebanking.jar query spending 1 groceries
প্রত্যাশিত আউটপুট:
Total spending for customer 1 under category groceries: 50
আপনি অন্যান্য বিভাগগুলিতেও খরচ খুঁজে পেতে পারেন (যা আমরা আগের ধাপে শ্রেণীবদ্ধ করেছি), অথবা একটি ভিন্ন গ্রাহক আইডি ব্যবহার করতে পারেন:
java -jar target/onlinebanking.jar query spending 1 transportation
java -jar target/onlinebanking.jar query spending 1 restaurants
java -jar target/onlinebanking.jar query spending 12 entertainment
সারাংশ
এই ধাপে, আপনি হুবহু মিলের প্রশ্নগুলির পাশাপাশি অস্পষ্ট এবং পূর্ণ-পাঠ্য অনুসন্ধানগুলি সম্পাদন করেছেন।
পরবর্তী
এরপর, আপনি ফেডারেটেড কোয়েরিগুলি সম্পাদন করার জন্য স্প্যানারকে Google BigQuery-এর সাথে একীভূত করবেন, যার ফলে আপনি আপনার রিয়েল-টাইম স্প্যানার ডেটাকে BigQuery ডেটার সাথে একত্রিত করতে পারবেন।
৮. BigQuery দিয়ে ফেডারেটেড কোয়েরি চালান
BigQuery ডেটাসেট তৈরি করুন
এই ধাপে, আপনি ফেডারেটেড কোয়েরি ব্যবহারের মাধ্যমে BigQuery এবং Spanner ডেটা একত্রিত করবেন।
এটি করার জন্য, ক্লাউড শেল কমান্ড লাইনে, প্রথমে একটি MarketingCampaigns ডেটাসেট তৈরি করুন:
bq mk --location=us-central1 MarketingCampaigns
প্রত্যাশিত আউটপুট:
Dataset '<PROJECT_ID>:MarketingCampaigns' successfully created.
এবং ডেটাসেটে একটি CustomerSegments টেবিল:
bq mk --table MarketingCampaigns.CustomerSegments CampaignId:STRING,CampaignName:STRING,CustomerId:INT64
প্রত্যাশিত আউটপুট:
Table '<PROJECT_ID>:MarketingCampaigns.CustomerSegments' successfully created.
এরপর, BigQuery থেকে Spanner-এর সাথে একটি সংযোগ তৈরি করুন:
bq mk --connection \
--connection_type=CLOUD_SPANNER \
--properties="{\"database\": \"projects/$GOOGLE_CLOUD_PROJECT/instances/cloudspanner-onlinebanking/databases/onlinebanking\", \"useParallelism\": true, \"useDataBoost\": true}" \
--location=us-central1 \
spanner-connection
প্রত্যাশিত আউটপুট:
Connection <PROJECT_NUMBER>.us-central1.spanner-connection successfully created
অবশেষে, BigQuery টেবিলে কিছু গ্রাহক যোগ করুন যা আমাদের Spanner ডেটার সাথে যুক্ত করা যেতে পারে:
bq query --use_legacy_sql=false '
INSERT INTO MarketingCampaigns.CustomerSegments (CampaignId, CampaignName, CustomerId)
VALUES
("campaign1", "Spring Promotion", 1),
("campaign1", "Spring Promotion", 3),
("campaign1", "Spring Promotion", 5),
("campaign1", "Spring Promotion", 7),
("campaign1", "Spring Promotion", 9),
("campaign1", "Spring Promotion", 11)'
প্রত্যাশিত আউটপুট:
Waiting on bqjob_r76a7ce76c5ec948f_0000019644bda052_1 ... (0s) Current status: DONE Number of affected rows: 6
আপনি BigQuery-তে জিজ্ঞাসা করে ডেটা উপলব্ধ কিনা তা যাচাই করতে পারেন:
bq query --use_legacy_sql=false "SELECT * FROM MarketingCampaigns.CustomerSegments"
প্রত্যাশিত আউটপুট:
+------------+------------------+------------+ | CampaignId | CampaignName | CustomerId | +------------+------------------+------------+ | campaign1 | Spring Promotion | 1 | | campaign1 | Spring Promotion | 5 | | campaign1 | Spring Promotion | 7 | | campaign1 | Spring Promotion | 9 | | campaign1 | Spring Promotion | 11 | | campaign1 | Spring Promotion | 3 | +------------+------------------+------------+
BigQuery-তে এই ডেটা বিভিন্ন ব্যাংক ওয়ার্কফ্লো-এর মাধ্যমে যোগ করা ডেটা প্রতিনিধিত্ব করে। উদাহরণস্বরূপ, এটি এমন গ্রাহকদের তালিকা হতে পারে যারা সম্প্রতি অ্যাকাউন্ট খুলেছেন বা মার্কেটিং প্রচারণার জন্য সাইন আপ করেছেন। আমাদের মার্কেটিং ক্যাম্পেইনে আমরা কোন গ্রাহকদের লক্ষ্য করতে চাই তাদের তালিকা নির্ধারণ করতে আমাদের BigQuery-তে এই ডেটা এবং Spanner-এ রিয়েল-টাইম ডেটা উভয়ই জিজ্ঞাসা করতে হবে এবং একটি ফেডারেটেড কোয়েরি আমাদের একক কোয়েরিতে এটি করার অনুমতি দেয়।
BigQuery দিয়ে একটি ফেডারেটেড কোয়েরি চালান
এরপর, আমরা অ্যাপ্লিকেশনটিতে একটি পদ্ধতি যোগ করব যাতে EXTERNAL_QUERY কল করে ফেডারেটেড কোয়েরি করা যায়। এটি BigQuery এবং Spanner জুড়ে গ্রাহকদের ডেটাতে যোগদান এবং বিশ্লেষণ করার অনুমতি দেবে, যেমন কোন গ্রাহকরা তাদের সাম্প্রতিক ব্যয়ের উপর ভিত্তি করে আমাদের মার্কেটিং প্রচারণার মানদণ্ড পূরণ করে তা সনাক্ত করা।
App.java খুলুন এবং আমদানিগুলি প্রতিস্থাপন করে শুরু করুন:
package com.google.codelabs;
import java.io.FileReader;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.Timestamp;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.connection.v1.ConnectionName;
import com.google.cloud.bigquery.JobException;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableResult;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Key;
import com.google.cloud.spanner.ReadOnlyTransaction;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.TimestampBound;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
import com.opencsv.CSVReader;
তারপর campaign পদ্ধতি যোগ করুন:
// Get customers for quarterly marketing campaign in BigQuery using Spanner data
public static void campaign(BigQuery bq, DatabaseId db, String location, String campaignId,
int threshold) {
// The BigQuery dataset, table, and Spanner connection must already exist for this to succeed
ConnectionName connection = ConnectionName.of(db.getInstanceId().getProject(), location,
"spanner-connection");
// Use a federated query to bring Spanner data into BigQuery
String bqQuery = "SELECT cs.CampaignName, c.CustomerId, c.FullName, t.TotalSpending\n"
+ "FROM MarketingCampaigns.CustomerSegments cs\n"
+ "JOIN EXTERNAL_QUERY('" + connection.toString() + "',\n"
+ " \"SELECT t.AccountId, SUM(t.Amount) AS TotalSpending"
+ " FROM TransactionLedger t"
+ " WHERE t.Timestamp >= TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -90 DAY)"
+ " GROUP BY t.AccountId"
+ " HAVING SUM(t.Amount) > " + threshold + "\"\n"
+ ") t ON cs.CustomerId = t.AccountId\n"
+ "JOIN EXTERNAL_QUERY('" + connection.toString() + "',\n"
+ " \"SELECT CustomerId, FullName"
+ " FROM Customers\"\n"
+ ") c ON c.CustomerId = cs.CustomerId\n"
+ "WHERE cs.CampaignId = '" + campaignId + "'";
try {
QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(bqQuery).build();
TableResult results = bq.query(queryConfig);
System.out.println("Customers for campaign (" + campaignId + "):");
results.iterateAll().forEach(row -> {
System.out.println(" " + row.get("FullName").getStringValue()
+ " (" + row.get("CustomerId").getStringValue() + ")");
});
} catch (JobException e) {
throw (BigQueryException) e.getCause();
} catch (InterruptedException e) {
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
প্রচারণার main পদ্ধতিতে আরেকটি কেস স্টেটমেন্ট যোগ করুন:
case "campaign":
String campaignId = (args.length >= 2) ? args[1] : "";
int threshold = (args.length >= 3) ? Integer.parseInt(args[2]) : 5000;
campaign(bigquery, db, location, campaignId, threshold);
break;
অবশেষে, printUsageAndExit পদ্ধতিতে ক্যাম্পেইন কীভাবে ব্যবহার করবেন তা সংযুক্ত করুন:
System.out.println(" java -jar target/onlinebanking.jar campaign campaign1 5000");
System.out.println(" - Use Federated Queries (BigQuery) to find customers that match a "
+ "marketing campaign by name based on a recent spending threshold.\n");
আপনার করা পরিবর্তনগুলি App.java তে সংরক্ষণ করুন।
অ্যাপ্লিকেশনটি পুনর্নির্মাণ করুন:
mvn package
গত ৩ মাসে কমপক্ষে $5000 খরচ করে থাকলে, মার্কেটিং ক্যাম্পেইনে ( campaign1 ) কাদের অন্তর্ভুক্ত করা উচিত তা নির্ধারণ করার জন্য একটি ফেডারেটেড কোয়েরি চালান, campaign কমান্ডটি চালিয়ে:
java -jar target/onlinebanking.jar campaign campaign1 5000
প্রত্যাশিত আউটপুট:
Customers for campaign (campaign1): Alice Smith (1) Eve Davis (5) Kelly Thomas (11)
আমরা এখন এই গ্রাহকদের এক্সক্লুসিভ অফার বা পুরষ্কার দিয়ে টার্গেট করতে পারি।
অথবা আমরা এমন আরও সংখ্যক গ্রাহকের সন্ধান করতে পারি যারা গত ৩ মাসে কম খরচের সীমা অর্জন করেছেন:
java -jar target/onlinebanking.jar campaign campaign1 2500
প্রত্যাশিত আউটপুট:
Customers for campaign (campaign1): Alice Smith (1) Charlie Williams (3) Eve Davis (5) Ivy Taylor (9) Kelly Thomas (11)
সারাংশ
এই ধাপে, আপনি BigQuery থেকে ফেডারেটেড কোয়েরিগুলি সফলভাবে সম্পাদন করেছেন যা রিয়েল-টাইম স্প্যানার ডেটা এনেছে।
পরবর্তী
এরপর, চার্জ এড়াতে আপনি এই কোডল্যাবের জন্য তৈরি রিসোর্সগুলি পরিষ্কার করতে পারেন।
৯. পরিষ্কার (ঐচ্ছিক)
এই ধাপটি ঐচ্ছিক। আপনি যদি আপনার স্প্যানার ইনস্ট্যান্সের সাথে পরীক্ষা চালিয়ে যেতে চান, তাহলে এই মুহূর্তে এটি পরিষ্কার করার প্রয়োজন নেই। তবে, আপনি যে প্রকল্পটি ব্যবহার করছেন তা থেকে ইনস্ট্যান্সের জন্য চার্জ করা অব্যাহত থাকবে। যদি আপনার এই ইনস্ট্যান্সের আর কোনও প্রয়োজন না থাকে, তাহলে এই চার্জগুলি এড়াতে আপনার এই সময়ে এটি মুছে ফেলা উচিত। স্প্যানার ইনস্ট্যান্স ছাড়াও, এই কোডল্যাব একটি BigQuery ডেটাসেট এবং সংযোগও তৈরি করেছে যা আর প্রয়োজন না হলে পরিষ্কার করা উচিত।
স্প্যানার ইনস্ট্যান্সটি মুছে ফেলুন:
gcloud spanner instances delete cloudspanner-onlinebanking
আপনি চালিয়ে যেতে চান তা নিশ্চিত করুন (টাইপ করুন Y ):
Delete instance [cloudspanner-onlinebanking]. Are you sure? Do you want to continue (Y/n)?
BigQuery সংযোগ এবং ডেটাসেট মুছুন:
bq rm --connection --location=us-central1 spanner-connection
bq rm -r MarketingCampaigns
BigQuery ডেটাসেট (টাইপ Y ) মুছে ফেলা নিশ্চিত করুন:
rm: remove dataset '<PROJECT_ID>:MarketingCampaigns'? (y/N)
১০. অভিনন্দন
🚀 আপনি একটি নতুন ক্লাউড স্প্যানার ইনস্ট্যান্স তৈরি করেছেন, একটি খালি ডাটাবেস তৈরি করেছেন, নমুনা ডেটা লোড করেছেন, উন্নত ক্রিয়াকলাপ এবং কোয়েরি করেছেন এবং (ঐচ্ছিকভাবে) ক্লাউড স্প্যানার ইনস্ট্যান্সটি মুছে ফেলেছেন।
আমরা যা কভার করেছি
- কিভাবে একটি স্প্যানার ইন্সট্যান্স সেটআপ করবেন।
- কিভাবে একটি ডাটাবেস এবং টেবিল তৈরি করবেন।
- আপনার স্প্যানার ডাটাবেস টেবিলে ডেটা কীভাবে লোড করবেন।
- স্প্যানার থেকে ভার্টেক্স এআই মডেলগুলিকে কীভাবে কল করবেন।
- ফাজি সার্চ এবং ফুল-টেক্সট সার্চ ব্যবহার করে আপনার স্প্যানার ডাটাবেস কীভাবে কোয়েরি করবেন।
- BigQuery থেকে Spanner-এর বিরুদ্ধে ফেডারেটেড কোয়েরি কীভাবে সম্পাদন করবেন।
- আপনার স্প্যানার ইন্সট্যান্সটি কীভাবে মুছে ফেলবেন।
এরপর কী?
- উন্নত স্প্যানার বৈশিষ্ট্য সম্পর্কে আরও জানুন, যার মধ্যে রয়েছে:
- উপলব্ধ স্প্যানার ক্লায়েন্ট লাইব্রেরিগুলি দেখুন।