ফায়ারবেসে, সমস্ত নোড ডেটা লোড না করে কোনও নোডের বাচ্চাদের সংখ্যা পাওয়ার উপায় আছে?


132

আপনি মাধ্যমে শিশু গণনা পেতে পারেন

firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); });

তবে আমি বিশ্বাস করি এটি সার্ভার থেকে এই নোডের পুরো উপ-গাছটি এনেছে। বিশাল তালিকাগুলির জন্য, মনে হয় এটি র‌্যাম এবং ল্যাটেন্সি নিবিড়। পুরো জিনিসটি এনে না রেখে কি গণনা (এবং / বা সন্তানের নামের একটি তালিকা) পাওয়ার কোনও উপায় আছে?


অনেক অনেক ধন্যবাদ আমি এটি চেষ্টা করেছিলাম এবং এটি আমার জন্য কাজ করেছে
আহমেদ মাহমুদ

আপনার কোড বড় ডেটা সেট হ্যান্ডেল করতে পারে না। আমি জাভা হ্যাপ স্পেসের কারণে ত্রুটির কারণ পেয়েছি। আমি এখনও কিছু বৈশিষ্ট্যের জন্য অপেক্ষা করছি।
পানুপং কংনার্ন

উত্তর:


98

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

ফায়ারবেসে বর্তমানে ডেটা লোড না করে শিশুদের গণনা করার কোনও উপায় নেই, তবে আমরা এটি যুক্ত করার পরিকল্পনা করি।

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

var upvotesRef = new Firebase('https://docs-examples.firebaseio.com/android/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');
upvotesRef.transaction(function (current_value) {
  return (current_value || 0) + 1;
});

আরও তথ্যের জন্য https://www.firebase.com/docs/transजे.html দেখুন

আপডেট: ফায়ারবেস সম্প্রতি ক্লাউড ফাংশন প্রকাশ করেছে। ক্লাউড ফাংশন সহ, আপনার নিজের সার্ভার তৈরি করার দরকার নেই। আপনি কেবল জাভাস্ক্রিপ্ট ফাংশন লিখে ফায়ারবেসে আপলোড করতে পারেন। ফায়ারবেস যখনই কোনও ঘটনা ঘটে তখন ফাংশন ট্রিগার করার জন্য দায়বদ্ধ।

আপনি উদাহরণস্বরূপ upvotes গণনা করতে চান, আপনার এই মত একটি কাঠামো তৈরি করা উচিত:

{
  "posts" : {
    "-JRHTHaIs-jNPLXOQivY" : {
      "upvotes_count":5,
      "upvotes" : {
      "userX" : true,
      "userY" : true,
      "userZ" : true,
      ...
    }
    }
  }
}

এবং তারপরে upvotes_countযখন upvotesনোডে একটি নতুন লিখন থাকবে তখন বাড়ানোর জন্য একটি জাভাস্ক্রিপ্ট ফাংশন লিখুন ।

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.countlikes = functions.database.ref('/posts/$postid/upvotes').onWrite(event => {
  return event.data.ref.parent.child('upvotes_count').set(event.data.numChildren());
});

ক্লাউড ফাংশন দিয়ে কীভাবে শুরু করবেন তা জানতে আপনি ডকুমেন্টেশনটি পড়তে পারেন ।

এছাড়াও, গণনা পোস্টের আর একটি উদাহরণ এখানে রয়েছে: https://github.com/firebase/function-sams/blob/master/child-count/funitions/index.js

জানুয়ারী 2018 আপডেট করুন

Firebase ডক্স তাই পরিবর্তে পরিবর্তিত হয়েছে eventআমরা এখন আছে changeএবং context

প্রদত্ত উদাহরণটি অভিযোগ করার সময় ত্রুটি ছুঁড়ে দেয় event.dataযা সংজ্ঞায়িত। এই নিদর্শনটি আরও ভালভাবে কাজ করছে বলে মনে হচ্ছে:

exports.countPrescriptions = functions.database.ref(`/prescriptions`).onWrite((change, context) => {
    const data = change.after.val();
    const count = Object.keys(data).length;
    return change.after.ref.child('_count').set(count);
});

``


74
আপনি কি কখনও এই জন্য সমর্থন যোগ করেছেন?
জিম কুপার

20
কোনও লেনদেনে ক্লায়েন্ট-সাইড কাউন্টারটি কি সুরক্ষিত? দেখে মনে হচ্ছে এটি সহজেই কৃত্রিমভাবে গণনা বাড়ানোর জন্য হ্যাক হতে পারে। এটি ভোটিং সিস্টেমের জন্য খারাপ হতে পারে।
সোভিয়েট

16
++ স্থানান্তর ব্যয় ব্যয় না করে গণনাটি পাওয়া সত্যিই চমৎকার হবে
জ্যারেড

27
এটি কখনও যুক্ত করা হয়েছে?
এলিজার

25
এই বৈশিষ্ট্যটি রোডম্যাপের কোনও খবর? ধন্যবাদ
পান্ডাইলো

37

এটি খেলায় কিছুটা দেরি হয়ে গেছে কারণ আরও বেশ কয়েকজন ইতিমধ্যে সুন্দরভাবে উত্তর দিয়েছেন তবে আমি কীভাবে এটি বাস্তবায়ন করতে পারি তা ভাগ করে নেব।

এটি ফায়ারবেস আরইএসটি এপিআই একটি shallow=trueপ্যারামিটার সরবরাহ করে এমন বিষয়ে জড়িত ।

ধরুন আপনার একটি postঅবজেক্ট রয়েছে এবং প্রত্যেকের একটিতে একটি সংখ্যা থাকতে পারে comments:

{
 "posts": {
  "$postKey": {
   "comments": {
     ...  
   }
  }
 }
}

আপনি অবশ্যই সমস্ত মন্তব্য, কেবলমাত্র সংখ্যার সংখ্যা আনতে চান না।

ধরে নিচ্ছি আপনার কাছে কোনও পোস্টের কী আছে, আপনি একটি GETঅনুরোধ পাঠাতে পারেন https://yourapp.firebaseio.com/posts/[the post key]/comments?shallow=true

এটি কী-মান জোড়াগুলির একটি অবজেক্ট ফিরিয়ে দেবে, যেখানে প্রতিটি কী একটি মন্তব্যের মূল এবং এর মান হ'ল true:

{
 "comment1key": true,
 "comment2key": true,
 ...,
 "comment9999key": true
}

এই প্রতিক্রিয়াটির আকার সমতুল্য ডেটা অনুরোধ করার চেয়ে অনেক ছোট, এবং এখন আপনি নিজের মানটি খুঁজে পেতে প্রতিক্রিয়াতে কীগুলির সংখ্যা গণনা করতে পারেন (উদাঃ মন্তব্যকাউন্ট = Object.keys(result).length)।

এটি সম্পূর্ণরূপে আপনার সমস্যার সমাধান করতে পারে না, কারণ আপনি এখনও কী কী সংখ্যা ফিরে পেয়েছেন তা গণনা করছেন, এবং পরিবর্তিত হিসাবে আপনি প্রয়োজনীয় মানটি সাবস্ক্রাইব করতে পারবেন না, তবে এটি কোনও পরিবর্তন পরিবর্তনের প্রয়োজন ছাড়াই ফিরে আসা ডেটার আকারকে হ্রাস করে দেয় স্কিমা।


অগভীর = সত্যটি পূর্ববর্তী উত্তরগুলির পরে একটি নতুন সংযোজন হওয়ায় এটি গ্রহণযোগ্য উত্তরটি তৈরি করতে পারে। এটি নিজে দেখার জন্য সময় ছিল না, তাই লোকেরা কী ভাবছেন তা দেখার জন্য কয়েক দিন অপেক্ষা করবেন ...
জোশ

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

যদি মন্তব্য কীগুলির কোনও বুলিয়ান মান না থাকে তবে তার পরিবর্তে বাচ্চা থাকে তবে কী কী কী-মান সংখ্যক কীগুলি ফেরত দেয়?
alltej

1
আপনি REST এপিআই ব্যবহার করে সতর্কতা অবলম্বন করতে চাইতে পারেন: স্টার্টআপসেন্সেকাপিটাল.
com/…

3
কেবল এটি উল্লেখ করতে যে আপনাকে .jsonইউআরএলটির শেষের দিকে যুক্ত করতে হবে, উদাহরণস্বরূপ:https://yourapp.firebaseio.com/posts/comments.json?shallow=true
ওসামা Xäwãñz

22

আপনি যেমন যান তেমন গণনা সংরক্ষণ করুন - এবং এটি প্রয়োগের জন্য বৈধতা ব্যবহার করুন। আমি একসাথে হ্যাক করেছি - একটি অনন্য ভোট এবং গণনা রাখার জন্য যা সামনে আসে !. এবারও আমার পরামর্শ পরীক্ষা করে দেখলাম! (কাট / পেস্ট ত্রুটি সত্ত্বেও!)।

'কৌশল' এখানে নোড অগ্রাধিকারটি ভোট গণনা হিসাবে ব্যবহার করা ...

তথ্যটি হ'ল:

ভোট / $ ইস্যুবিংভোটডন / ইউজার / $ অনন্যআইডঅফভোটার = এইভোটসাউন্ট, অগ্রাধিকার = এইভোটসকাউন্ট ভোট / $ ইস্যুবিংভোটডন / কাউন্ট = 'ইউজার /' + $ আইডোফ্লাস্টভোটার, অগ্রাধিকার = কাউন্টফ্লোস্টভোট

,"vote": {
  ".read" : true
  ,".write" : true
  ,"$issue" : {
    "user" : {
      "$user" : {
        ".validate" : "!data.exists() && 
             newData.val()==data.parent().parent().child('count').getPriority()+1 &&
             newData.val()==newData.GetPriority()" 

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

      }
    }
    ,"count" : {
      ".validate" : "data.parent().child(newData.val()).val()==newData.getPriority() &&
             newData.getPriority()==data.getPriority()+1 "
    }

গণনা (সত্যই সর্বশেষ ভোটার) - ভোট অবশ্যই উপস্থিত থাকতে হবে এবং এর গণনা সমান নতুন গণনা, && নতুন গণনা (অগ্রাধিকার) কেবল একজনের কাছে যেতে পারে।

  }
}

বিভিন্ন ব্যবহারকারীর দ্বারা 10 টি ভোট যুক্ত করার জন্য স্ক্রিপ্ট স্ক্রিপ্ট (উদাহরণস্বরূপ, আইডির নকল, ব্যবহারকারীর প্রযোজনে auth.uid হওয়া উচিত)। বৈধতা ব্যর্থ দেখতে 10 (i--) দ্বারা গণনা করুন।

<script src='https://cdn.firebase.com/v0/firebase.js'></script>
<script>
  window.fb = new Firebase('https:...vote/iss1/');
  window.fb.child('count').once('value', function (dss) {
    votes = dss.getPriority();
    for (var i=1;i<10;i++) vote(dss,i+votes);
  } );

function vote(dss,count)
{
  var user='user/zz' + count; // replace with auth.id or whatever
  window.fb.child(user).setWithPriority(count,count);
  window.fb.child('count').setWithPriority(user,count);
}
</script>

এখানে 'ঝুঁকি' হ'ল একটি ভোট দেওয়া হয়েছে, তবে গণনাটি আপডেট হয়নি (হ্যাকিং বা স্ক্রিপ্ট ব্যর্থতা)। এ কারণেই ভোটের একটি অনন্য 'অগ্রাধিকার' রয়েছে - বর্তমান গণনার চেয়ে অগ্রাধিকারের সাথে কোনও ভোট নেই বলে নিশ্চিত করে স্ক্রিপ্টটি সত্যই শুরু করা উচিত, যদি এটির নিজস্ব কাজ করার আগে সেই লেনদেনটি সম্পন্ন করা উচিত - আপনার ক্লায়েন্টকে পরিষ্কার করার জন্য আপনার জন্য আপ :)

আপনি শুরু করার আগে গণনাটিকে একটি অগ্রাধিকার দিয়ে শুরু করা দরকার - ফরজ আপনাকে এটি করতে দেয় না, সুতরাং স্টাব স্ক্রিপ্টের প্রয়োজন হয় (বৈধতা কার্যকর হওয়ার আগে!)।


এটা সত্যিই দারুন!!! দ্বন্দ্বের ক্ষেত্রে কী হয়, তবে? অর্থাৎ দু'জন লোক একই সাথে ভোট দেয়? আদর্শভাবে আপনি কেবলমাত্র তাদের একটি ভোট বাতিল করার পরিবর্তে স্বয়ংক্রিয়ভাবে সমাধান করতে চান ... সম্ভবত কোনও লেনদেনেই ভোটটি করবেন?
জোশ

হাই জোশ, যুক্তিযুক্তভাবে সত্যিকারের ভোট কেবলমাত্র ব্যর্থ হতে পারে যদি পূর্ববর্তী ভোট দেওয়া হয় তবে মোট আপডেট হয়নি (এখনও)। আমার ২ য় থেকে শেষ প্যারাটি এতে coversেকে রেখেছে - আমি আগের ভোটারদের মোটামুটি আপডেট যেভাবেই হোক (প্রতিটি সময়) করব - যদি এটির প্রয়োজন না হয়, তবে কী? এবং তারপরে এই ভোটগুলি আপডেট হয়। যতক্ষণ ভোট কার্যকর হয়। যদি আপনার 'মোট' আপডেট ব্যর্থ হয়, পরবর্তী ভোটার এটি ঠিক করে দেবে, তাই আবার - তবে কী?
pperrin

আমি সত্যিই কেবল "গণনা" নোডটি 'শেষের ভোট' নোড হওয়া উচিত বলে প্রলোভন করছি - সুতরাং প্রতিটি ভোটার / ক্লায়েন্ট আপডেট / সংশোধন / মেরামত করে যে নোড / মান এবং তারপরে তার নিজস্ব ভোট যুক্ত করে - (পরবর্তী ভোটারকে আপডেটটি দেওয়া মোট 'এই' ভোট অন্তর্ভুক্ত)। - আপনি যদি আমার ড্রিফট পান ...
pperrin

4

একটি মেঘ ফাংশন লিখুন এবং নোড গণনা আপডেট করুন।

// below function to get the given node count.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.userscount = functions.database.ref('/users/')
    .onWrite(event => {

      console.log('users number : ', event.data.numChildren());


      return event.data.ref.parent.child('count/users').set(event.data.numChildren());
    }); 

উল্লেখ করুন: https://firebase.google.com/docs/function/datedia-events

root-- | | ব্যবহারকারীরা (এই নোডে সমস্ত ব্যবহারকারীর তালিকা রয়েছে) |
?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.