ফায়ারস্টোর পাইপলাইন অপারেশন শুরু করুন

পটভূমি

পাইপলাইন কোয়েরি হল ফায়ারস্টোরের জন্য একটি নতুন কোয়েরি ইন্টারফেস। এটি জটিল এক্সপ্রেশন সহ উন্নত কোয়েরি কার্যকারিতা প্রদান করে। এটি min, max, substring, regex_match এবং array_contains_all এর মতো অনেক নতুন ফাংশনের জন্য সমর্থন যোগ করে। পাইপলাইন কোয়েরিগুলির সাথে, সূচক তৈরি সম্পূর্ণরূপে ঐচ্ছিক, নতুন কোয়েরি তৈরির প্রক্রিয়াটিকে সহজতর করে। পাইপলাইন কোয়েরিগুলি কোয়েরি আকারের উপর অনেক সীমাবদ্ধতাও সরিয়ে দেয় যা আপনাকে or or in বড় নির্দিষ্ট করার অনুমতি দেয়।

শুরু করা

ক্লায়েন্ট SDK ইনস্টল এবং আরম্ভ করতে, শুরু করুন নির্দেশিকায় দেওয়া নির্দেশাবলী পড়ুন।

বাক্য গঠন

নিম্নলিখিত বিভাগগুলি পাইপলাইন কোয়েরির সিনট্যাক্সের একটি সারসংক্ষেপ প্রদান করে।

ধারণা

পাইপলাইন কোয়েরির সাথে একটি উল্লেখযোগ্য পার্থক্য হল স্পষ্ট "পর্যায়" ক্রম প্রবর্তন। এর ফলে আরও জটিল কোয়েরি প্রকাশ করা সম্ভব হয়। তবে, এটি বিদ্যমান কোয়েরি ইন্টারফেস থেকে একটি উল্লেখযোগ্য বিচ্যুতি যেখানে পর্যায়গুলির ক্রম নিহিত ছিল। নিম্নলিখিত পাইপলাইন কোয়েরি উদাহরণটি বিবেচনা করুন:

Web

const pipeline = db.pipeline()
  // Step 1: Start a query with collection scope
  .collection("cities")
  // Step 2: Filter the collection
  .where(field("population").greaterThan(100000))
  // Step 3: Sort the remaining documents
  .sort(field("name").ascending())
  // Step 4: Return the top 10. Note applying the limit earlier in the
  // pipeline would have unintentional results.
  .limit(10);
সুইফট
let pipeline = db.pipeline()
  // Step 1: Start a query with collection scope
  .collection("cities")
  // Step 2: Filter the collection
  .where(Field("population").greaterThan(100000))
  // Step 3: Sort the remaining documents
  .sort([Field("name").ascending()])
  // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have
  // unintentional results.
  .limit(10)

Kotlin

val pipeline = db.pipeline()
    // Step 1: Start a query with collection scope
    .collection("cities")
    // Step 2: Filter the collection
    .where(field("population").greaterThan(100000))
    // Step 3: Sort the remaining documents
    .sort(field("name").ascending())
    // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have
    // unintentional results.
    .limit(10)

Java

Pipeline pipeline = db.pipeline()
    // Step 1: Start a query with collection scope
    .collection("cities")
    // Step 2: Filter the collection
    .where(field("population").greaterThan(100000))
    // Step 3: Sort the remaining documents
    .sort(field("name").ascending())
    // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have
    // unintentional results.
    .limit(10);
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

pipeline = (
    client.pipeline()
    .collection("cities")
    .where(Field.of("population").greater_than(100_000))
    .sort(Field.of("name").ascending())
    .limit(10)
)

আরম্ভকরণ

পাইপলাইন কোয়েরিগুলির একটি খুব পরিচিত সিনট্যাক্স রয়েছে যা বিদ্যমান Cloud Firestore কোয়েরিগুলি থেকে আসে। শুরু করার জন্য, আপনাকে নিম্নলিখিতটি লিখে একটি কোয়েরি শুরু করতে হবে:

Web

const { getFirestore } = require("firebase/firestore");
const { execute } = require("firebase/firestore/pipelines");
const database = getFirestore(app, "enterprise");
const pipeline = database.pipeline();
সুইফট
let firestore = Firestore.firestore(database: "enterprise")
let pipeline = firestore.pipeline()

Kotlin

val firestore = Firebase.firestore("enterprise")
val pipeline = firestore.pipeline()

Java

FirebaseFirestore firestore = FirebaseFirestore.getInstance("enterprise");
PipelineSource pipeline = firestore.pipeline();
পাইথন
firestore_client = firestore.client(default_app, "your-new-enterprise-database")
pipeline = firestore_client.pipeline()

গঠন

পাইপলাইন কোয়েরি তৈরি করার সময় কয়েকটি শব্দ বোঝা গুরুত্বপূর্ণ: পর্যায়, অভিব্যক্তি এবং ফাংশন।

একটি কোয়েরিতে ধাপ এবং রাশি প্রদর্শনের উদাহরণ

পর্যায়: একটি পাইপলাইনে এক বা একাধিক পর্যায় থাকতে পারে। যুক্তিসঙ্গতভাবে, এগুলি কোয়েরি কার্যকর করার জন্য নেওয়া ধাপগুলির (বা পর্যায়গুলির) ধারাবাহিকতাকে প্রতিনিধিত্ব করে। দ্রষ্টব্য: বাস্তবে, কর্মক্ষমতা উন্নত করার জন্য পর্যায়গুলি বাইরে থেকে সম্পাদন করা যেতে পারে। তবে, এটি কোয়েরির উদ্দেশ্য বা সঠিকতা পরিবর্তন করে না।

এক্সপ্রেশন: স্টেজগুলি প্রায়শই এমন এক্সপ্রেশন গ্রহণ করে যা আপনাকে আরও জটিল প্রশ্ন প্রকাশ করার সুযোগ দেয়। এক্সপ্রেশন সহজ হতে পারে এবং eq("a", 1) এর মতো একটি ফাংশন নিয়ে গঠিত হতে পারে। আপনি and(eq("a", 1), eq("b", 2)).

ক্ষেত্র বনাম ধ্রুবক রেফারেন্স

পাইপলাইন কোয়েরি জটিল এক্সপ্রেশন সমর্থন করে। তাই, একটি মান একটি ক্ষেত্র বা একটি ধ্রুবক প্রতিনিধিত্ব করে কিনা তা পার্থক্য করার প্রয়োজন হতে পারে। নিম্নলিখিত উদাহরণটি বিবেচনা করুন:

Web

const pipeline = db.pipeline()
  .collection("cities")
  .where(field("name").equal(constant("Toronto")));
সুইফট
let pipeline = db.pipeline()
  .collection("cities")
  .where(Field("name").equal(Constant("Toronto")))

Kotlin

val pipeline = db.pipeline()
    .collection("cities")
    .where(field("name").equal(constant("Toronto")))

Java

Pipeline pipeline = db.pipeline()
    .collection("cities")
    .where(field("name").equal(constant("Toronto")));
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field, Constant

pipeline = (
    client.pipeline()
    .collection("cities")
    .where(Field.of("name").equal(Constant.of("Toronto")))
)

পর্যায়

ইনপুট পর্যায়

ইনপুট পর্যায়টি একটি কোয়েরির প্রথম পর্যায়কে প্রতিনিধিত্ব করে। এটি আপনার জিজ্ঞাসা করা ডকুমেন্টের প্রাথমিক সেটকে সংজ্ঞায়িত করে। পাইপলাইন কোয়েরির ক্ষেত্রে, এটি মূলত বিদ্যমান কোয়েরির মতো, যেখানে বেশিরভাগ কোয়েরি একটি collection(...) অথবা collection_group(...) পর্যায় দিয়ে শুরু হয়। দুটি নতুন ইনপুট পর্যায় হল database() এবং documents(...) যেখানে database() ডাটাবেসের সমস্ত ডকুমেন্ট ফেরত দেওয়ার অনুমতি দেয়, যখন documents(...) একটি ব্যাচ পঠিত ডকুমেন্টের মতোই কাজ করে।

Web

let results;

// Return all restaurants in San Francisco
results = await execute(db.pipeline().collection("cities/sf/restaurants"));

// Return all restaurants
results = await execute(db.pipeline().collectionGroup("restaurants"));

// Return all documents across all collections in the database (the entire database)
results = await execute(db.pipeline().database());

// Batch read of 3 documents
results = await execute(db.pipeline().documents([
  doc(db, "cities", "SF"),
  doc(db, "cities", "DC"),
  doc(db, "cities", "NY")
]));
সুইফট
var results: Pipeline.Snapshot

// Return all restaurants in San Francisco
results = try await db.pipeline().collection("cities/sf/restaurants").execute()

// Return all restaurants
results = try await db.pipeline().collectionGroup("restaurants").execute()

// Return all documents across all collections in the database (the entire database)
results = try await db.pipeline().database().execute()

// Batch read of 3 documents
results = try await db.pipeline().documents([
  db.collection("cities").document("SF"),
  db.collection("cities").document("DC"),
  db.collection("cities").document("NY")
]).execute()

Kotlin

var results: Task<Pipeline.Snapshot>

// Return all restaurants in San Francisco
results = db.pipeline().collection("cities/sf/restaurants").execute()

// Return all restaurants
results = db.pipeline().collectionGroup("restaurants").execute()

// Return all documents across all collections in the database (the entire database)
results = db.pipeline().database().execute()

// Batch read of 3 documents
results = db.pipeline().documents(
    db.collection("cities").document("SF"),
    db.collection("cities").document("DC"),
    db.collection("cities").document("NY")
).execute()

Java

Task<Pipeline.Snapshot> results;

// Return all restaurants in San Francisco
results = db.pipeline().collection("cities/sf/restaurants").execute();

// Return all restaurants
results = db.pipeline().collectionGroup("restaurants").execute();

// Return all documents across all collections in the database (the entire database)
results = db.pipeline().database().execute();

// Batch read of 3 documents
results = db.pipeline().documents(
    db.collection("cities").document("SF"),
    db.collection("cities").document("DC"),
    db.collection("cities").document("NY")
).execute();
পাইথন
# Return all restaurants in San Francisco
results = client.pipeline().collection("cities/sf/restaurants").execute()

# Return all restaurants
results = client.pipeline().collection_group("restaurants").execute()

# Return all documents across all collections in the database (the entire database)
results = client.pipeline().database().execute()

# Batch read of 3 documents
results = (
    client.pipeline()
    .documents(
        client.collection("cities").document("SF"),
        client.collection("cities").document("DC"),
        client.collection("cities").document("NY"),
    )
    .execute()
)

অন্যান্য সকল ধাপের মতো, এই ইনপুট ধাপগুলির ফলাফলের ক্রম স্থিতিশীল নয়। যদি একটি নির্দিষ্ট ক্রম পছন্দ হয় তবে সর্বদা একটি sort(...) অপারেটর যোগ করা উচিত।

কোথায়

where(...) পর্যায়টি পূর্ববর্তী পর্যায় থেকে তৈরি নথিগুলির উপর একটি ঐতিহ্যবাহী ফিল্টার অপারেশন হিসাবে কাজ করে এবং বেশিরভাগ ক্ষেত্রে বিদ্যমান প্রশ্নের জন্য বিদ্যমান "where" সিনট্যাক্সকে প্রতিফলিত করে। যে কোনও নথি যেখানে একটি প্রদত্ত অভিব্যক্তি একটি অ- true মান মূল্যায়ন করে তা ফেরত দেওয়া নথি থেকে ফিল্টার করা হয়।

একাধিক where(...) স্টেটমেন্ট একসাথে শৃঙ্খলিত হতে পারে এবং একটি and(...) এক্সপ্রেশন হিসেবে কাজ করে। উদাহরণস্বরূপ, নিম্নলিখিত দুটি কোয়েরি যৌক্তিকভাবে সমতুল্য এবং বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে।

Web

let results;

results = await execute(db.pipeline().collection("books")
  .where(field("rating").equal(5))
  .where(field("published").lessThan(1900))
);

results = await execute(db.pipeline().collection("books")
  .where(and(field("rating").equal(5), field("published").lessThan(1900)))
);
সুইফট
var results: Pipeline.Snapshot

results = try await db.pipeline().collection("books")
  .where(Field("rating").equal(5))
  .where(Field("published").lessThan(1900))
  .execute()

results = try await db.pipeline().collection("books")
  .where(Field("rating").equal(5) && Field("published").lessThan(1900))
  .execute()

Kotlin

var results: Task<Pipeline.Snapshot>

results = db.pipeline().collection("books")
    .where(field("rating").equal(5))
    .where(field("published").lessThan(1900))
    .execute()

results = db.pipeline().collection("books")
    .where(Expression.and(field("rating").equal(5),
      field("published").lessThan(1900)))
    .execute()

Java

Task<Pipeline.Snapshot> results;

results = db.pipeline().collection("books")
    .where(field("rating").equal(5))
    .where(field("published").lessThan(1900))
    .execute();

results = db.pipeline().collection("books")
    .where(Expression.and(
        field("rating").equal(5),
        field("published").lessThan(1900)
    ))
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import And, Field

results = (
    client.pipeline()
    .collection("books")
    .where(Field.of("rating").equal(5))
    .where(Field.of("published").less_than(1900))
    .execute()
)

results = (
    client.pipeline()
    .collection("books")
    .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900)))
    .execute()
)

ক্ষেত্রগুলি নির্বাচন করুন / যোগ করুন এবং সরান

select(...) , add_fields(...) , & remove_fields(...) এই তিনটি ধাপ আপনাকে পূর্ববর্তী ধাপ থেকে ফিরে আসা ক্ষেত্রগুলি পরিবর্তন করার অনুমতি দেয়। এই তিনটি ধাপকে সাধারণত প্রজেকশন-স্টাইল পর্যায় বলা হয়।

select(...) এবং add_fields(...) আপনাকে ব্যবহারকারীর দ্বারা প্রদত্ত ক্ষেত্রের নামের সাথে একটি এক্সপ্রেশনের ফলাফল নির্দিষ্ট করার অনুমতি দেয়। যে এক্সপ্রেশনের ফলে ত্রুটি দেখা দেয় তার ফলে একটি null মান তৈরি হয়। select(...) শুধুমাত্র নির্দিষ্ট ক্ষেত্রের নাম সহ ডকুমেন্টগুলি ফেরত দেবে যখন add_fields(...) পূর্ববর্তী পর্যায়ের স্কিমা প্রসারিত করবে (সম্ভাব্যভাবে অভিন্ন ক্ষেত্রের নাম সহ মানগুলি ওভাররাইট করা)।

remove_fields(...) পূর্ববর্তী পর্যায় থেকে অপসারণের জন্য ক্ষেত্রগুলির একটি সেট নির্দিষ্ট করার অনুমতি দেয়। বিদ্যমান নেই এমন ক্ষেত্রের নাম নির্দিষ্ট করা একটি অপ্রয়োজনীয় কাজ।

নীচে "রিস্ট্রিক্ট দ্য ফিল্ডস টু রিটার্ন" বিভাগটি দেখুন, তবে সাধারণভাবে ক্লায়েন্টের প্রয়োজনীয় ফিল্ডগুলিতে ফলাফল সীমাবদ্ধ করার জন্য এই ধরণের পর্যায় ব্যবহার করা বেশিরভাগ প্রশ্নের জন্য খরচ এবং বিলম্ব কমাতে সহায়ক।

সমষ্টিগত / স্বতন্ত্র

aggregate(...) পর্যায় আপনাকে ইনপুট ডকুমেন্টের উপর একের পর এক সমষ্টি সম্পাদন করতে দেয়। ডিফল্টরূপে, সমস্ত ডকুমেন্ট একসাথে একত্রিত করা হয়, তবে একটি ঐচ্ছিক grouping আর্গুমেন্ট প্রদান করা যেতে পারে, যা ইনপুট ডকুমেন্টগুলিকে বিভিন্ন বাকেটে একত্রিত করার অনুমতি দেয়।

Web

const results = await execute(db.pipeline()
  .collection("books")
  .aggregate(
    field("rating").average().as("avg_rating")
  )
  .distinct(field("genre"))
);
সুইফট
let results = try await db.pipeline()
  .collection("books")
  .aggregate([
    Field("rating").average().as("avg_rating")
  ], groups: [
    Field("genre")
  ])
  .execute()

Kotlin

val results = db.pipeline()
    .collection("books")
    .aggregate(
        AggregateStage
            .withAccumulators(AggregateFunction.average("rating").alias("avg_rating"))
            .withGroups(field("genre"))
    )
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
    .collection("books")
    .aggregate(AggregateStage
        .withAccumulators(
            AggregateFunction.average("rating").alias("avg_rating"))
        .withGroups(field("genre")))
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

results = (
    client.pipeline()
    .collection("books")
    .aggregate(
        Field.of("rating").average().as_("avg_rating"), groups=[Field.of("genre")]
    )
    .execute()
)

যখন groupings নির্দিষ্ট করা না থাকে, তখন এই পর্যায়টি শুধুমাত্র একটি একক নথি তৈরি করবে, অন্যথায় groupings মানের প্রতিটি অনন্য সমন্বয়ের জন্য একটি নথি তৈরি করা হবে।

distinct(...) পর্যায় হল একটি সরলীকৃত সমষ্টি অপারেটর যা কোনও সঞ্চয়কারী ছাড়াই কেবল অনন্য groupings তৈরি করতে দেয়। এটি অন্যান্য সকল ক্ষেত্রে aggregate(...) এর সাথে একই রকম আচরণ করে। নীচে একটি উদাহরণ দেওয়া হল:

Web

const results = await execute(db.pipeline()
  .collection("books")
  .distinct(
    field("author").toUpper().as("author"),
    field("genre")
  )
);
সুইফট
let results = try await db.pipeline()
  .collection("books")
  .distinct([
    Field("author").toUpper().as("author"),
    Field("genre")
  ])
  .execute()

Kotlin

val results = db.pipeline()
    .collection("books")
    .distinct(
        field("author").toUpper().alias("author"),
        field("genre")
    )
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
    .collection("books")
    .distinct(
        field("author").toUpper().alias("author"),
        field("genre")
    )
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

results = (
    client.pipeline()
    .collection("books")
    .distinct(Field.of("author").to_upper().as_("author"), "genre")
    .execute()
)

ফাংশন

ফাংশন হল এক্সপ্রেশন এবং জটিল কোয়েরি তৈরির জন্য একটি বিল্ডিং ব্লক। উদাহরণ সহ ফাংশনের সম্পূর্ণ তালিকার জন্য, ফাংশন রেফারেন্স দেখুন। দ্রুত মনে করিয়ে দেওয়ার জন্য, একটি সাধারণ কোয়েরির গঠন বিবেচনা করুন:

একটি কোয়েরিতে পর্যায় এবং ফাংশন প্রদর্শনের উদাহরণ

অনেক ধাপে এক বা একাধিক ফাংশন ধারণকারী এক্সপ্রেশন গ্রহণ করা হয়। সবচেয়ে সাধারণ ফাংশন ব্যবহার where(...) এবং select(...) ধাপে পাওয়া যাবে। দুটি প্রধান ধরণের ফাংশন রয়েছে যার সাথে আপনার পরিচিত হওয়া উচিত:

Web

let results;

// Type 1: Scalar (for use in non-aggregation stages)
// Example: Return the min store price for each book.
results = await execute(db.pipeline().collection("books")
  .select(field("current").logicalMinimum(field("updated")).as("price_min"))
);

// Type 2: Aggregation (for use in aggregate stages)
// Example: Return the min price of all books.
results = await execute(db.pipeline().collection("books")
  .aggregate(field("price").minimum().as("min_price"))
);
সুইফট
var results: Pipeline.Snapshot

// Type 1: Scalar (for use in non-aggregation stages)
// Example: Return the min store price for each book.
results = try await db.pipeline().collection("books")
  .select([
    Field("current").logicalMinimum(["updated"]).as("price_min")
  ])
  .execute()

// Type 2: Aggregation (for use in aggregate stages)
// Example: Return the min price of all books.
results = try await db.pipeline().collection("books")
  .aggregate([Field("price").minimum().as("min_price")])
  .execute()

Kotlin

var results: Task<Pipeline.Snapshot>

// Type 1: Scalar (for use in non-aggregation stages)
// Example: Return the min store price for each book.
results = db.pipeline().collection("books")
    .select(
        field("current").logicalMinimum("updated").alias("price_min")
    )
    .execute()

// Type 2: Aggregation (for use in aggregate stages)
// Example: Return the min price of all books.
results = db.pipeline().collection("books")
    .aggregate(AggregateFunction.minimum("price").alias("min_price"))
    .execute()

Java

Task<Pipeline.Snapshot> results;

// Type 1: Scalar (for use in non-aggregation stages)
// Example: Return the min store price for each book.
results = db.pipeline().collection("books")
    .select(
        field("current").logicalMinimum("updated").alias("price_min")
    )
    .execute();

// Type 2: Aggregation (for use in aggregate stages)
// Example: Return the min price of all books.
results = db.pipeline().collection("books")
    .aggregate(AggregateFunction.minimum("price").alias("min_price"))
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

# Type 1: Scalar (for use in non-aggregation stages)
# Example: Return the min store price for each book.
results = (
    client.pipeline()
    .collection("books")
    .select(
        Field.of("current").logical_minimum(Field.of("updated")).as_("price_min")
    )
    .execute()
)

# Type 2: Aggregation (for use in aggregate stages)
# Example: Return the min price of all books.
results = (
    client.pipeline()
    .collection("books")
    .aggregate(Field.of("price").minimum().as_("min_price"))
    .execute()
)

সীমা

বেশিরভাগ ক্ষেত্রেই এন্টারপ্রাইজ সংস্করণ কোয়েরির আকারের উপর কোনও সীমা আরোপ করে না। অন্য কথায়, আপনি একটি IN বা OR কোয়েরিতে অল্প সংখ্যক মানের মধ্যে সীমাবদ্ধ নন। পরিবর্তে, দুটি প্রাথমিক সীমা সম্পর্কে আপনার সচেতন থাকা উচিত:

  • সময়সীমা: ৬০ সেকেন্ড (স্ট্যান্ডার্ড সংস্করণের অনুরূপ)।
  • মেমোরি ব্যবহার: কোয়েরি সম্পাদনের সময় বস্তুগত ডেটার পরিমাণের উপর ১২৮ MiB সীমা।

ত্রুটি

বিভিন্ন কারণে আপনার কোয়েরি ব্যর্থ হতে পারে। এখানে সাধারণ ত্রুটি এবং আপনি যে পদক্ষেপ নিতে পারেন তার একটি লিঙ্ক রয়েছে:

ত্রুটি কোড অ্যাকশন
DEADLINE_EXCEEDED আপনি যে কোয়েরিটি সম্পাদন করছেন তা ৬০ সেকেন্ডের বেশি সময় পেরিয়ে গেছে এবং অতিরিক্ত অপ্টিমাইজেশনের প্রয়োজন। টিপসের জন্য পারফরম্যান্স বিভাগটি দেখুন। যদি আপনি সমস্যাটির মূল কারণ খুঁজে না পান, তাহলে টিমের সাথে যোগাযোগ করুন।
RESOURCE_EXHAUSTED আপনি যে কোয়েরিটি সম্পাদন করছেন তা মেমোরির সীমা অতিক্রম করে এবং অতিরিক্ত অপ্টিমাইজেশনের প্রয়োজন। টিপসের জন্য পারফরম্যান্স বিভাগটি দেখুন। যদি আপনি সমস্যাটির মূল কারণ খুঁজে না পান, তাহলে টিমের সাথে যোগাযোগ করুন।
INTERNAL সহায়তার জন্য দলের সাথে যোগাযোগ করুন

কর্মক্ষমতা

বিদ্যমান কোয়েরির বিপরীতে, পাইপলাইন কোয়েরিগুলিতে সর্বদা একটি সূচক উপস্থিত থাকার প্রয়োজন হয় না। এর অর্থ হল একটি কোয়েরি বিদ্যমান কোয়েরির তুলনায় উচ্চতর ল্যাটেন্সি প্রদর্শন করতে পারে যা FAILED_PRECONDITION অনুপস্থিত সূচক ত্রুটির সাথে সাথেই ব্যর্থ হয়ে যেত। পাইপলাইন কোয়েরির কর্মক্ষমতা উন্নত করতে, আপনি কয়েকটি পদক্ষেপ নিতে পারেন।

সূচী তৈরি করুন

ব্যবহৃত সূচক

কোয়েরি ব্যাখ্যা আপনাকে সনাক্ত করতে সাহায্য করে যে আপনার কোয়েরিটি কোনও সূচক দ্বারা পরিবেশিত হচ্ছে কিনা অথবা টেবিল স্ক্যানের মতো কম দক্ষ অপারেশনে ফিরে যাচ্ছে কিনা। যদি আপনার কোয়েরিটি কোনও সূচক থেকে সম্পূর্ণরূপে পরিবেশিত না হয়, তাহলে আপনি নির্দেশাবলী অনুসরণ করে একটি সূচক তৈরি করতে পারেন।

সূচী তৈরি করা

সূচক তৈরি করতে আপনি বিদ্যমান সূচক ব্যবস্থাপনা ডকুমেন্টেশন অনুসরণ করতে পারেন। একটি সূচক তৈরি করার আগে, ফায়ারস্টোরে সূচকগুলির সাথে সাধারণ সর্বোত্তম অনুশীলনগুলির সাথে নিজেকে পরিচিত করুন। আপনার কোয়েরি সূচকগুলিকে কাজে লাগাতে পারে তা নিশ্চিত করার জন্য, নিম্নলিখিত ক্রমানুসারে ক্ষেত্রগুলি সহ সূচক তৈরি করার সর্বোত্তম অনুশীলনগুলি অনুসরণ করুন:

  1. সমতা ফিল্টারে ব্যবহৃত সকল ক্ষেত্র (যেকোনো ক্রমে)
  2. সমস্ত ক্ষেত্র যা সাজানো হবে (একই ক্রমে)
  3. ক্যোয়ারী সীমাবদ্ধতা নির্বাচনের ক্রমহ্রাসমান ক্রমে পরিসর বা অসমতা ফিল্টারে ব্যবহৃত ক্ষেত্রগুলি

উদাহরণস্বরূপ, নিম্নলিখিত প্রশ্নের জন্য,

Web

const results = await execute(db.pipeline()
  .collection("books")
  .where(field("published").lessThan(1900))
  .where(field("genre").equal("Science Fiction"))
  .where(field("rating").greaterThan(4.3))
  .sort(field("published").descending())
);
সুইফট
let results = try await db.pipeline()
  .collection("books")
  .where(Field("published").lessThan(1900))
  .where(Field("genre").equal("Science Fiction"))
  .where(Field("rating").greaterThan(4.3))
  .sort([Field("published").descending()])
  .execute()

Kotlin

val results = db.pipeline()
    .collection("books")
    .where(field("published").lessThan(1900))
    .where(field("genre").equal("Science Fiction"))
    .where(field("rating").greaterThan(4.3))
    .sort(field("published").descending())
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
    .collection("books")
    .where(field("published").lessThan(1900))
    .where(field("genre").equal("Science Fiction"))
    .where(field("rating").greaterThan(4.3))
    .sort(field("published").descending())
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

results = (
    client.pipeline()
    .collection("books")
    .where(Field.of("published").less_than(1900))
    .where(Field.of("genre").equal("Science Fiction"))
    .where(Field.of("rating").greater_than(4.3))
    .sort(Field.of("published").descending())
    .execute()
)

প্রস্তাবিত সূচক হল (genre [...], published DESC, avg_rating DESC). books একটি সংগ্রহ সুযোগ সূচক।

সূচক ঘনত্ব

ক্লাউড ফায়ারস্টোর স্পার্স এবং নন-স্পার্স ইনডেক্স সমর্থন করে। আরও তথ্যের জন্য, ইনডেক্স ডেনসিটি দেখুন।

আচ্ছাদিত প্রশ্ন + মাধ্যমিক সূচী

ফায়ারস্টোর সম্পূর্ণ ডকুমেন্ট আনা এড়িয়ে যেতে পারে এবং যদি ফেরত দেওয়া সমস্ত ক্ষেত্র একটি সেকেন্ডারি ইনডেক্সে উপস্থিত থাকে তবে কেবল সূচক থেকে ফলাফল ফেরত পাঠাতে পারে। এটি সাধারণত একটি উল্লেখযোগ্য ল্যাটেন্সি (এবং খরচ) উন্নতির দিকে পরিচালিত করে। নীচের নমুনা কোয়েরি ব্যবহার করে:

Web

const results = await execute(db.pipeline()
  .collection("books")
  .where(field("category").like("%fantasy%"))
  .where(field("title").exists())
  .where(field("author").exists())
  .select(field("title"), field("author"))
);
সুইফট
let results = try await db.pipeline()
  .collection("books")
  .where(Field("category").like("%fantasy%"))
  .where(Field("title").exists())
  .where(Field("author").exists())
  .select([Field("title"), Field("author")])
  .execute()

Kotlin

val results = db.pipeline()
    .collection("books")
    .where(field("category").like("%fantasy%"))
    .where(field("title").exists())
    .where(field("author").exists())
    .select(field("title"), field("author"))
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
    .collection("books")
    .where(field("category").like("%fantasy%"))
    .where(field("title").exists())
    .where(field("author").exists())
    .select(field("title"), field("author"))
    .execute();
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

results = (
    client.pipeline()
    .collection("books")
    .where(Field.of("category").like("%fantasy%"))
    .where(Field.of("title").exists())
    .where(Field.of("author").exists())
    .select("title", "author")
    .execute()
)

যদি ডাটাবেসে ইতিমধ্যেই (category [...], title [...], author [...]) books জন্য একটি সংগ্রহ সুযোগ সূচক থাকে, তাহলে এটি মূল নথি থেকে কিছু আনা এড়াতে পারে। এই ক্ষেত্রে সূচকের ক্রম কোন ব্যাপার না, [...] এটি বোঝাতে ব্যবহৃত হয়।

ক্ষেত্রগুলিকে ফেরত দেওয়ার জন্য সীমাবদ্ধ করুন

ডিফল্টরূপে, একটি Firestore কোয়েরি একটি ডকুমেন্টের সমস্ত ক্ষেত্র ফেরত দেয়, যা ঐতিহ্যবাহী সিস্টেমে SELECT * এর অনুরূপ। তবে যদি আপনার অ্যাপ্লিকেশনের শুধুমাত্র ক্ষেত্রগুলির একটি উপসেটের প্রয়োজন হয়, তাহলে select(...) অথবা restrict(...) পর্যায়গুলি এই ফিল্টারিং সার্ভার-সাইডটি পুশ করার জন্য ব্যবহার করা যেতে পারে। এটি প্রতিক্রিয়ার আকার (নেটওয়ার্কের বহির্গমন খরচ হ্রাস) এবং ল্যাটেন্সি উভয়ই হ্রাস করবে।

সমস্যা সমাধানের সরঞ্জাম

প্রশ্ন ব্যাখ্যা করুন

কোয়েরি এক্সপ্লেইন আপনাকে এক্সিকিউশন মেট্রিক্সে দৃশ্যমানতা এবং ব্যবহৃত সূচক সম্পর্কে বিশদ আনতে দেয়।

মেট্রিক্স

পাইপলাইন কোয়েরিগুলি যদি বিদ্যমান ফায়ারস্টোর মেট্রিক্সের সাথে সম্পূর্ণরূপে একত্রিত হয়।

জ্ঞাত সমস্যা / সীমাবদ্ধতা

বিশেষায়িত সূচী

পাইপলাইন কোয়েরিগুলি এখনও বিদ্যমান array-contains এবং vector ইনডেক্স প্রকারগুলিকে সমর্থন করে না। কেবল এই ধরণের কোয়েরিগুলি প্রত্যাখ্যান করার পরিবর্তে, ফায়ারস্টোর অন্যান্য বিদ্যমান ascending এবং descending সূচকগুলি ব্যবহার করার চেষ্টা করবে। আশা করা হচ্ছে যে ব্যক্তিগত প্রিভিউয়ের সময় এই ধরণের array_contains বা find_nearest এক্সপ্রেশন সহ পাইপলাইন কোয়েরিগুলি তাদের বিদ্যমান সমতুল্যগুলির তুলনায় ধীর হবে। এর ফলে।

পৃষ্ঠাঙ্কন

প্রাইভেট প্রিভিউয়ের সময় ফলাফল সেটের উপর সহজেই পৃষ্ঠাঙ্কন করার সুবিধা সমর্থিত নয়। নীচে দেখানো হয়েছে যে, সমতুল্য where(...) & sort(...) ধাপগুলিকে চেইন আপ করে এটি করা যেতে পারে।

Web

// Existing pagination via `startAt()`
const q =
  query(collection(db, "cities"), orderBy("population"), startAt(1000000));

// Private preview workaround using pipelines
const pageSize = 2;
const pipeline = db.pipeline()
  .collection("cities")
  .select("name", "population", "__name__")
  .sort(field("population").descending(), field("__name__").ascending());

// Page 1 results
let snapshot = await execute(pipeline.limit(pageSize));

// End of page marker
const lastDoc = snapshot.results[snapshot.results.length - 1];

// Page 2 results
snapshot = await execute(
  pipeline
    .where(
      or(
        and(
          field("population").equal(lastDoc.get("population")),
          field("__name__").greaterThan(lastDoc.ref)
        ),
        field("population").lessThan(lastDoc.get("population"))
      )
    )
    .limit(pageSize)
);
সুইফট
// Existing pagination via `start(at:)`
let query = db.collection("cities").order(by: "population").start(at: [1000000])

// Private preview workaround using pipelines
let pipeline = db.pipeline()
  .collection("cities")
  .where(Field("population").greaterThanOrEqual(1000000))
  .sort([Field("population").descending()])

Kotlin

// Existing pagination via `startAt()`
val query = db.collection("cities").orderBy("population").startAt(1000000)

// Private preview workaround using pipelines
val pipeline = db.pipeline()
    .collection("cities")
    .where(field("population").greaterThanOrEqual(1000000))
    .sort(field("population").descending())

Java

// Existing pagination via `startAt()`
Query query = db.collection("cities").orderBy("population").startAt(1000000);

// Private preview workaround using pipelines
Pipeline pipeline = db.pipeline()
    .collection("cities")
    .where(field("population").greaterThanOrEqual(1000000))
    .sort(field("population").descending());
পাইথন
from google.cloud.firestore_v1.pipeline_expressions import Field

# Existing pagination via `start_at()`
query = (
    client.collection("cities")
    .order_by("population")
    .start_at({"population": 1_000_000})
)

# Private preview workaround using pipelines
pipeline = (
    client.pipeline()
    .collection("cities")
    .where(Field.of("population").greater_than_or_equal(1_000_000))
    .sort(Field.of("population").descending())
)

এমুলেটর সাপোর্ট

এমুলেটরটি এখনও পাইপলাইন কোয়েরি সমর্থন করে না।

রিয়েলটাইম এবং অফলাইন সাপোর্ট

পাইপলাইন কোয়েরিগুলিতে এখনও রিয়েলটাইম এবং অফলাইন ক্ষমতা নেই।

এরপর কি?