سؤال

أنا الرقم واحد طريقة العد مثل هذا:

foo = db.GqlQuery("SELECT * FROM bar WHERE baz = 'baz')
my_count = foo.count()

ما لا يعجبني هو العد سوف تكون محدودة إلى 1000 ماكس و الاستعلام بلدي ربما تكون بطيئة.أي شخص هناك مع الحل?لدي واحد في الاعتبار ، لكنه لا يشعر نظيفة.إلا إذا كان GQL حقيقي وظيفة العد...

هل كانت مفيدة؟

المحلول

و+1 للاستجابة Jehiah ل.

وطريقة الرسمي والمباركة على الحصول على عدادات الكائن على GAE هو بناء مكافحة sharded . على الرغم من اسمه السبر بشكل كبير، وهذا واضح وصريح جدا.

نصائح أخرى

وعليك أن الوجه تفكيرك عند العمل مع مخزن البيانات تحجيم مثل GAE للقيام الحسابات الخاصة بك في خط الهجوم. في هذه الحالة هذا يعني أنك بحاجة للحفاظ على عدادات لكل baz وزيادة لهم كلما قمت بإضافة bar جديدة، بدلا من عد في وقت العرض.

class CategoryCounter(db.Model):
    category = db.StringProperty()
    count = db.IntegerProperty(default=0)

وبعد ذلك عند إنشاء كائن بار، زيادة العداد

def createNewBar(category_name):
  bar = Bar(...,baz=category_name)

  counter = CategoryCounter.filter('category =',category_name).get()
  if not counter:
    counter = CategoryCounter(category=category_name)
  else:
    counter.count += 1
  bar.put()
  counter.put()

db.run_in_transaction(createNewBar,'asdf')

والآن لديك وسيلة سهلة للحصول على العد لأي فئة معينة

CategoryCounter.filter('category =',category_name).get().count

وظائف عدد في كافة قواعد البيانات بطيئة (على سبيل المثال، O (ن)) - مخزن البيانات GAE يجعل مجرد أن أكثر وضوحا. كما يقترح Jehiah، تحتاج إلى تخزين عدد حسابها في كيان وأشير إلى أنه إذا كنت تريد تطويره.

وهذه ليست فريدة من نوعها لمحرك التطبيقات - قواعد البيانات الأخرى مجرد إخفاء بطريقة أفضل، حتى النقطة التي كنت تحاول الاعتماد عشرات الآلاف من السجلات مع كل طلب، وصفحتك تقديم موعد لتزيد أضعافا مضاعفة .. .

ووفقا ل GqlQuery.count() الوثائق ، يمكنك تعيين limit أن تكون بعض رقم أكبر من 1000:

from models import Troll
troll_count = Troll.all(keys_only=True).count(limit=31337)

وعدادات Sharded هي الطريقة الصحيحة لتتبع أرقام مثل هذا، كما قال الناس، ولكن إذا كنت هذا الرقم في وقت متأخر من لعبة (مثلي)، ثم ستحتاج إلى تهيئة العدادات من العد الفعلي لل شاء. ولكن هذا هو وسيلة رائعة لحرق من خلال حصتك خالية من مخزن البيانات العمليات الصغيرة (50،000 أعتقد). في كل مرة تشغيل التعليمات البرمجية، فإنه سيتم استخدام ما يصل العديد من مكتب خدمات المشاريع كما أن هناك كائنات النموذج.

وأنا لم أحاول ذلك، وهذا هو الموارد خنزير المطلق، ولكن ربما بالتكرار مع .fetch() وتحديد الإزاحة ستعمل؟

LIMIT=1000
def count(query):
   result = offset = 0
   gql_query = db.GqlQuery(query)
   while True:
     count = gql_query.fetch(LIMIT, offset)
     if count < LIMIT:
       return result
     result += count
     offset += LIMIT

وحل orip ليعمل مع قليل من التغيير والتبديل:

LIMIT=1000
def count(query):
    result = offset = 0
    gql_query = db.GqlQuery(query)
    while True:
        count = len(gql_query.fetch(LIMIT, offset))
        result += count
        offset += LIMIT
        if count < LIMIT:
            return result

لدينا الآن مخزن البيانات الاحصائيات التي يمكن استخدامها للاستعلام التهم كيان وغيرها من البيانات. هذه القيم لا تعكس دائما أحدث التغييرات كما يتم تحديثها مرة كل 24-48 ساعة. تحقق من وثائق (انظر الرابط أدناه) لمزيد من التفاصيل:

مخزن البيانات الاحصائيات

كما أشار @Dimu, احصائيات حسابها من قبل جوجل على أساس دوري اللائق الذهاب إلى الموارد عندما حسابات دقيقة لا حاجة ٪ من السجلات لا تتغير بشكل كبير خلال أي يوم من الأيام.

الاستعلام عن إحصاءات معين نوع, يمكنك استخدام ما يلي GQL هيكل:

select * from __Stat_Kind__ where kind_name = 'Person'

هناك عدد من الخصائص التي تم إرجاعها بواسطة هذه التي قد تكون مفيدة:

  • count - عدد من الكيانات من هذا النوع
  • bytes -- إجمالي حجم جميع الكيانات المخزنة من هذا النوع
  • timestamp - وهو اعتبارا من تاريخ/وقت عندما احصائيات آخر محسوب

رمز المثال

للإجابة على متابعة مسألة نشر تعليق على جوابي أنا الآن توفير بعض العينات C# التعليمات البرمجية التي أنا باستخدام ، والتي المسلم قد لا تكون قوية كما ينبغي أن يكون ، ولكن يبدو أن العمل بالنسبة لي موافق:

/// <summary>Returns an *estimated* number of entities of a given kind</summary>
public static long GetEstimatedEntityCount(this DatastoreDb database, string kind)
{
    var query = new GqlQuery
    {
        QueryString = $"select * from __Stat_Kind__ where kind_name = '{kind}'",
        AllowLiterals = true
    };
    var result = database.RunQuery(query);
    return (long) (result?.Entities?[0]?["count"] ?? 0L);
}

وأفضل الحل قد يبدو قليلا غير بديهية، ولكنه يعمل كبيرة في جميع التطبيقات إلى AppEngine بلدي. بدلا من الاعتماد على KEY صحيح وطرق العد ()، يمكنك إضافة حقل عدد صحيح الخاصة بك لنوع البيانات. قد يبدو الإسراف حتى يكون لديك في الواقع أكثر من 1000 السجلات، وتكتشف فجأة أن جلب () والحد () لا تعمل PAST THE BOUNDARY 1000 RECORD.

def MyObj(db.Model):
  num = db.IntegerProperty()

عند إنشاء كائن جديد، يجب استرداد أعلى المفتاح يدويا:

max = MyObj.all().order('-num').get()
if max : max = max.num+1
else : max = 0
newObj = MyObj(num = max)
newObj.put()

وهذا قد يبدو مثل مضيعة للاستعلام، ولكن الحصول على () إرجاع سجل واحد من أعلى المؤشر. فهو سريع جدا.

وبعد ذلك، عندما تريد جلب الماضي الحد الكائن 1000th لل، يمكنك ببساطة القيام به:

MyObj.all().filter('num > ' , 2345).fetch(67)

وكنت قد فعلت ذلك بالفعل عندما قرأت مراجعة لاذعا آرال البلقان و: http://aralbalkan.com/1504. أنه أمر محبط، ولكن عندما تعتاد على ذلك وكنت أدرك كيف أسرع بكثير من هذا العدد () على ديسيبل العلائقية، وسوف لا تمانع ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top