গুগল ফায়ার স্টোর - এক রাউন্ড ট্রিপে একাধিক আইডির মাধ্যমে কীভাবে ডকুমেন্ট পাবেন?


105

আমি ভাবছি যে ফায়ার স্টোরে এক রাউন্ড ট্রিপে (নেটওয়ার্ক কল) আইডির তালিকা করে একাধিক নথি পাওয়া সম্ভব কিনা?


4
আপনি ধরে নিয়েছেন বলে মনে হচ্ছে যে রাউন্ডট্রিপগুলি আপনার অ্যাপ্লিকেশনটিতে পারফরম্যান্স সমস্যা তৈরি করছে। আমি এটা ধরে নিব না। ফায়ারবেস যেমন ক্ষেত্রে অনুরোধগুলি পাইপলাইন করে , এই জাতীয় ক্ষেত্রে দুর্দান্ত কাজ করার ইতিহাস রয়েছে । যদিও আমি এই দৃশ্যে ফায়ারস্টোর কীভাবে আচরণ করে তা পরীক্ষা করে দেখিনি, আমি এটি অনুমান করার আগে একটি পারফরম্যান্স সমস্যার সমস্যার প্রমাণ দেখতে চাই।
ফ্র্যাঙ্ক ভ্যান পাফেলেন

4
আসুন আমি কাগজপত্র প্রয়োজন বলে a, b, cকিছু করতে। আমি তিনটি জন্য অনুরোধ পৃথক অনুরোধ সমান্তরাল। a100 মিমি লাগে, 150 মিমি bনেয় এবং c3000 মিমি লাগে। ফলস্বরূপ, টাস্কটি করতে আমাকে 3000 মিমি অপেক্ষা করতে হবে। এটি maxতাদের হতে চলেছে । আনার জন্য নথির সংখ্যা বড় হলে এটি ঝুঁকিপূর্ণ হতে চলেছে। নেটওয়ার্ক স্থিতির উপর নির্ভর করে, আমি মনে করি এটি একটি সমস্যা হয়ে উঠতে পারে।
জুন

4
সবাইকে একক হিসাবে প্রেরণে কি SELECT * FROM docs WHERE id IN (a,b,c)একই পরিমাণ সময় লাগবে? আমি পার্থক্যটি দেখতে পাচ্ছি না, যেহেতু সংযোগটি একবার ইনস্টল হয়ে গেছে এবং বাকিটি তার উপর পাইপলাইনযুক্ত। সময় (সংযোগের প্রাথমিক প্রতিষ্ঠার পরে) সমস্ত নথি + 1 রাউন্ড ট্রিপের লোড সময়, উভয় পদ্ধতির জন্য একই। যদি এটি আপনার জন্য আলাদা আচরণ করে, আপনি কি কোনও নমুনা ভাগ করতে পারেন (আমার লিঙ্কিত প্রশ্নে)?
ফ্র্যাঙ্ক ভ্যান পাফেলেন

আমি মনে করি তোমাকে হারিয়েছি আপনি যখন এটি পাইপলাইনযুক্ত বলছেন, তখন আপনার অর্থ কি ফায়ারস্টোর স্বয়ংক্রিয়ভাবে দলবদ্ধ হয় এবং তাদের সার্ভারে ডাটাবেসে এক রাউন্ড ট্রিপে কোয়েরি পাঠায়?
জুন

এফওয়াইআই, আমি রাউন্ড ট্রিপ বলতে যা বোঝাতে চাইছি তা ক্লায়েন্টের ডেটাবেজে একটি নেটওয়ার্ক কল। আমি জিজ্ঞাসা করছি যে ফায়ারস্টোর দ্বারা একাধিক প্রশ্নগুলি স্বয়ংক্রিয়ভাবে এক রাউন্ড ট্রিপ হিসাবে গোষ্ঠী করা হয়েছে, বা সমান্তরালভাবে একাধিক রাউন্ড ট্রিপ হিসাবে একাধিক প্রশ্নগুলি সম্পাদন করা হয়েছে।
জুন

উত্তর:


101

যদি আপনি নোডের মধ্যে থাকেন:

https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701

/**
* Retrieves multiple documents from Firestore.
*
* @param {...DocumentReference} documents - The document references
* to receive.
* @returns {Promise<Array.<DocumentSnapshot>>} A Promise that
* contains an array with the resulting document snapshots.
*
* @example
* let documentRef1 = firestore.doc('col/doc1');
* let documentRef2 = firestore.doc('col/doc2');
*
* firestore.getAll(documentRef1, documentRef2).then(docs => {
*   console.log(`First document: ${JSON.stringify(docs[0])}`);
*   console.log(`Second document: ${JSON.stringify(docs[1])}`);
* });
*/

এটি সার্ভারের জন্য বিশেষত এসডিকে

আপডেট: "ক্লাউড ফায়ার স্টোর [ক্লায়েন্ট-সাইড এসডিকে] এখন অনুসন্ধানগুলিতে সমর্থন করে!"

https://firebase.googleblog.com/2019/11/cloud-firestore- હવે-supports-in-queries.html

myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])


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

4
আমি দুঃখিত, কমনাকিইঙ্গা ... আমি প্রায় এক বছরে কোনও ফায়ারবেস স্টাফ করিনি এবং এই মুহূর্তে আসলেই সহায়তা করতে পারি না (আরে দেখুন, আমি আজ এই এক বছর আগে এই উত্তরটি পোস্ট করেছি!)
নিক ফ্রাঞ্চেসিনা

4
ক্লায়েন্ট-সাইড এসডিকেও এখন এই কার্যকারিতা সরবরাহ করে। : একটি উদাহরণ জন্য jeodonara এর উত্তর দেখার stackoverflow.com/a/58780369
ফ্রাঙ্ক ভ্যান Puffelen

6
সতর্কতা: ফিল্টারটি বর্তমানে 10 টি আইটেমের মধ্যে সীমাবদ্ধ। আপনি যখন উত্পাদন হিট করতে চলেছেন তখন আপনি সম্ভবত এটি অকেজো খুঁজে পেতে পারেন।
মার্টিন ক্রেমার

9
আসলে আপনার ব্যবহার করা দরকার firebase.firestore.FieldPath.documentId()এবং না'id'
ম্যাডডকস

23

তারা সবেমাত্র এই কার্যকারিতাটি ঘোষণা করেছে, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html

এখন আপনি এর মতো প্রশ্নগুলি ব্যবহার করতে পারেন তবে মনে রাখবেন যে ইনপুট আকারটি 10 ​​এর বেশি হতে পারে না।

userCollection.where('uid', 'in', ["1231","222","2131"])


যেখানে চেয়ে বরং সেখানে একটি জিজ্ঞাসা আছে। এবং আমি জানি না যে কীভাবে নির্দিষ্ট সংগ্রহের সাথে সম্পর্কিত নথিগুলির আইডির তালিকা থেকে একাধিক নথির জন্য ক্যোয়ারী ডিজাইন করা যায়। সাহায্য করুন.
সংকলন ত্রুটি শেষ

17
আপনি কি এই চেষ্টা করতে পারেন? db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
জিডোনারা

আপনাকে ধন্যবাদ, বিশেষতfirebase.firestore.FieldPath.documentId()
ইভান চেরনিখ

11

অনুশীলনে আপনি ফায়ার স্টোর ব্যবহার করবেন get

async getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    const users = await this.firestore.getAll(...refs)
    console.log(users.map(doc => doc.data()))
}

বা প্রতিশ্রুতি বাক্য গঠন সঙ্গে

getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    this.firestore.getAll(...refs).then(users => console.log(users.map(doc => doc.data())))
}

4
এটি সত্যই নির্বাচিত উত্তর হওয়া উচিত কারণ এটি আপনাকে 10 টিরও বেশি
আইডির

10

না, এখনই ক্লাউড ফায়ারস্টোর এসডিকে ব্যবহার করে একাধিক পঠন অনুরোধগুলির ব্যাচ করার কোনও উপায় নেই এবং অতএব আপনি একবারে সমস্ত ডেটা পড়তে পারবেন তার গ্যারান্টি দেওয়ার কোনও উপায় নেই।

তবে ফ্রাঙ্ক ভ্যান পাফেলেন উপরের মন্তব্যে যেমন বলেছেন যে এর অর্থ এই নয় যে 3 টি নথি আনার ফলে একটি নথি আনার মতো 3x তত কম হবে। এখানে কোনও সিদ্ধান্তে পৌঁছানোর আগে আপনার নিজের পরিমাপ সম্পাদন করা ভাল।


4
জিনিসটি হ'ল আমি ফায়ার স্টোরে স্থানান্তরিত হওয়ার আগে ফায়ারস্টোরের কর্মক্ষমতা সম্পর্কিত তাত্ত্বিক সীমাটি জানতে চাই। আমি স্থানান্তর করতে চাই না এবং তারপরে বুঝতে পারি যে এটি আমার ব্যবহারের ক্ষেত্রে যথেষ্ট ভাল নয় good
জুন

4
হাই, এখানে কোস একটি বিবেচনা আছে। ধরা যাক আমি আমার সমস্ত বন্ধুর আইডির তালিকা সংরক্ষণ করেছি এবং নম্বরটি 500 টি I
তাপস মুখোপাধ্যায়

4
আপনি যদি 500 টি নথি পড়ার চেষ্টা করছেন তবে এটি 500 রিড লাগে। আপনি যদি সমস্ত 500 টি নথি থেকে আপনার প্রয়োজনীয় তথ্যগুলি একক অতিরিক্ত নথিতে সংযুক্ত করেন তবে এটি কেবল একটি পঠন করে। এটিকে বলা হয় ক্লাউড ফায়ার স্টোর সহ বেশিরভাগ নোএসকিউএল ডাটাবেসে ডেটা সদৃশকরণ সাজানো বেশ স্বাভাবিক।
ফ্র্যাঙ্ক ভ্যান পাফেলেন

4
MongoDB মধ্যে উদাহরণস্বরূপ @FrankvanPuffelen, আপনি ভালো অবজেক্ট-ব্যবহার করতে পারেন stackoverflow.com/a/32264630/648851
সিটিয়ান লিউ 21

4
@ ফ্র্যাঙ্কওয়ানপুফেলেনের মতোই বলেছেন, নুএসকিউএল ডাটাবেসে ডেটা ডুপ্লিকেশন খুব সাধারণ। এখানে আপনাকে নিজেকে জিজ্ঞাসা করতে হবে যে এই ডেটাগুলি কতবার পড়তে হয় এবং কতটা আপ টু ডেট হওয়া দরকার। আপনি যদি 500 জন ব্যবহারকারীর তথ্য সঞ্চয় করেন তবে আসুন তাদের নাম + ফটো + আইডি বলুন, আপনি সেগুলি একটি পঠন করে নিতে পারেন। তবে আপনার যদি আপ-টু-ডেটের প্রয়োজন হয় তবে আপনাকে সম্ভবত এই রেফারেন্সগুলি আপডেট করার জন্য মেঘ ফাংশনটি ব্যবহার করতে হবে যখনই প্রত্যেকবার ব্যবহারকারী তাদের নাম / ফটো আপডেট করে, তাই মেঘ ফাংশন চালিয়ে + কিছু লেখার কাজ করে। "ডান" / "আরও ভাল" বাস্তবায়ন নেই, এটি কেবল আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে।
স্ক্যানকাম

10

আপনি এই জাতীয় ফাংশন ব্যবহার করতে পারেন:

function getById (path, ids) {
  return firestore.getAll(
    [].concat(ids).map(id => firestore.doc(`${path}/${id}`))
  )
}

এটি একটি একক আইডি দিয়ে কল করা যেতে পারে:

getById('collection', 'some_id')

বা আইডিগুলির একটি অ্যারে:

getById('collection', ['some_id', 'some_other_id'])

5

অবশ্যই এটি করার সর্বোত্তম উপায় হ'ল একটি মেঘের ফাংশনে ফায়ারস্টোরের আসল ক্যোয়ারী প্রয়োগ করা? তারপরে ক্লায়েন্টের থেকে ফায়ারবেসে কেবল একক রাউন্ড ট্রিপ কল আসবে, যা মনে হচ্ছে আপনি যা চাইছেন তা।

আপনি সত্যই আপনার সার্ভারের মতো আপনার সমস্ত ডেটা অ্যাক্সেস লজিককে পাশাপাশি রাখতে চান।

অভ্যন্তরীণভাবে ফায়ারবেসে নিজেই একই সংখ্যক কল আসবে, তবে এগুলি সমস্তই বাহ্যিক নেটওয়ার্কের চেয়ে গুগলের অতি দ্রুততম আন্তঃসংযোগগুলি জুড়ে থাকবে এবং ফ্রাঙ্ক ভ্যান পাফেলেন যে পাইপলাইনের বর্ণনা দিয়েছিল তার সাথে মিলিয়ে আপনার দুর্দান্ত পারফরম্যান্স পাওয়া উচিত এই পদ্ধতির.


4
ক্লাউড ফাংশনে প্রয়োগটি সংরক্ষণ করা আপনার এমন কিছু ক্ষেত্রে সঠিক সিদ্ধান্ত যেখানে আপনার জটিল যুক্তি রয়েছে তবে সম্ভবত আপনি কেবলমাত্র একাধিক আইডির সাথে একটি তালিকা মার্জ করতে চান এমন ক্ষেত্রে নয়। আপনি যা হারাবেন তা হ'ল ক্লায়েন্ট সাইড ক্যাচিং এবং নিয়মিত কলগুলি থেকে স্ট্যান্ডার্ডাইজড রিটার্ন ফর্ম্যাটিং। এটি আমার অ্যাপ্লিকেশনগুলিতে কিছু ক্ষেত্রে সমাধান হওয়ার চেয়ে বেশি পারফরম্যান্স সমস্যা সৃষ্টি করেছে যখন আমি এই পদ্ধতির ব্যবহার করেছি।
যিরমিয় 20

5

আপনি যদি ঝাঁকুনি ব্যবহার করছেন তবে আপনি নিম্নলিখিতগুলি করতে পারেন:

Firestore.instance.collection('your collection name').where(FieldPath.documentId, whereIn:[list containing multiple document IDs]).getDocuments();

এটি এমন এক ভবিষ্যতকে ফিরিয়ে দেবে List<DocumentSnapshot>যা আপনাকে উপযুক্ত মনে হলে পুনরাবৃত্তি করতে পারে।


2

অ্যান্ড্রয়েড এসডিকে দিয়ে কোটলিনে আপনি কীভাবে এমন কিছু করবেন তা এখানে রয়েছে।
অগত্যা এক রাউন্ড ট্রিপে নাও যেতে পারে তবে ফলটি কার্যকরভাবে গোষ্ঠী করে এবং অনেক নেস্টেড কলব্যাক এড়ায়।

val userIds = listOf("123", "456")
val userTasks = userIds.map { firestore.document("users/${it!!}").get() }

Tasks.whenAllSuccess<DocumentSnapshot>(userTasks).addOnSuccessListener { documentList ->
    //Do what you need to with the document list
}

নোট করুন যে নির্দিষ্ট দস্তাবেজগুলি আনা সমস্ত দস্তাবেজ আনার এবং ফলাফল ফিল্টার করার চেয়ে অনেক ভাল। এটি কারণ ফায়ারস্টোর আপনাকে ক্যোয়ারির ফলাফল সেটটির জন্য চার্জ করে।


4
সুন্দরভাবে কাজ করে, ঠিক আমি যা খুঁজছিলাম!
জর্জি

1

আমি আশা করি এটি আপনাকে সহায়তা করে, এটি আমার পক্ষে কাজ করে।

getCartGoodsData(id) {

    const goodsIDs: string[] = [];

    return new Promise((resolve) => {
      this.fs.firestore.collection(`users/${id}/cart`).get()
        .then(querySnapshot => {
          querySnapshot.forEach(doc => {
            goodsIDs.push(doc.id);
          });

          const getDocs = goodsIDs.map((id: string) => {
            return this.fs.firestore.collection('goods').doc(id).get()
              .then((docData) => {
                return docData.data();
              });
          });

          Promise.all(getDocs).then((goods: Goods[]) => {
            resolve(goods);
          });
        });
    });
  }

0

এই মুহূর্তে ফায়ার স্টোরে এটি সম্ভব হবে বলে মনে হয় না। আলেকজান্ডারের উত্তর কেন গৃহীত হয়েছে তা আমি বুঝতে পারছি না, তিনি যে সমাধানটি প্রস্তাব করেছেন কেবল "ব্যবহারকারী" সংগ্রহের সমস্ত নথি ফিরিয়ে দেয়।

আপনার যা করা দরকার তার উপর নির্ভর করে আপনার প্রদর্শিত প্রাসঙ্গিক ডেটাটি নকল করা উচিত এবং প্রয়োজনের সময় কেবলমাত্র একটি সম্পূর্ণ ডকুমেন্টের জন্য অনুরোধ করা উচিত।


-1

আপনি সবচেয়ে ভাল করতে পারেন তাPromise.all আপনার ক্লায়েন্ট হিসাবেব্যবহার না করে তারপরে.allএগিয়ে যাওয়ার আগেঅবশ্যইপড়ারজন্য অপেক্ষা করতে হবে।

পাঠগুলি ইটারেট করুন এবং সেগুলি স্বাধীনভাবে সমাধান করুন। ক্লায়েন্টের পক্ষে, এটি সম্ভবত UI এ ফোটে যা বেশ কয়েকটি অগ্রগতি লোডার চিত্র স্বাধীনভাবে মানগুলির সমাধান করে। তবে, .allপাঠকদের সমাধান না হওয়া পর্যন্ত পুরো ক্লায়েন্টকে হিমায়িত করার চেয়ে এটি ভাল ।

অতএব, সমস্ত সিঙ্ক্রোনাস ফলাফল অবিলম্বে দর্শনে ফেলে দিন, তারপরে অবিচ্ছিন্ন ফলাফলগুলি পৃথকভাবে সমাধান হওয়ার সাথে সাথে আসুন। এটি ক্ষুদ্রতম পার্থক্যের মতো মনে হতে পারে তবে আপনার ক্লায়েন্টের ইন্টারনেট সংযোগ যদি দুর্বল থাকে (যেমন আমার কাছে বর্তমানে এই কফি শপে রয়েছে), পুরো ক্লায়েন্টের অভিজ্ঞতা কয়েক সেকেন্ডের জন্য হিমায়িত করার ফলে সম্ভবত এই 'অ্যাপ্লিকেশনটি সফলভাবে' নিয়ে আসে।


4
এটি অবিচ্ছিন্ন, ব্যবহারের জন্য প্রচুর ব্যবহারের কেস রয়েছে Promise.all... এটি প্রয়োজনীয় কিছু "হিমায়িত" করতে হবে না
রায়ান টেইলর

আপনি যখন আপনার সমস্ত ডেটা লোড করার প্রয়োজন হয় তখন বেশ কয়েকটি ব্যবহারের ঘটনা ঘটে থাকে, সুতরাং অপেক্ষা (কোনও উপযুক্ত বার্তা সহ একজন স্পিনারের মতো, আপনার মতো কোনও ইউআইকে "হিমায়িত" করার দরকার নেই) প্রতিশ্রুতি দ্বারা সমস্ত প্রয়োজন হতে পারে .. আপনি এখানে কী ধরণের পণ্য তৈরি করছেন তার উপর এটি নির্ভর করে। এই জাতীয় মন্তব্যগুলি আমার নিজের মতামতের কাছে অত্যন্ত অপ্রাসঙ্গিক এবং এর মধ্যে কোনও "সেরা" শব্দ হওয়া উচিত নয়। এটি সত্যিকারের প্রতিটি ব্যবহারের ক্ষেত্রে যেটির মুখোমুখি হতে পারে এবং আপনার অ্যাপ ব্যবহারকারীর জন্য কী করছে তার উপর নির্ভর করে doing
স্ক্যানকাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.