الطريقة الأكثر كفاءة لتتناسب مع عدد معين من العناصر في قائمة DB.ModelProperty

StackOverflow https://stackoverflow.com/questions/1197330

سؤال

بالنسبة إلى هذا سؤال مختلف ولكن ليس غير مرتبط سوف أستعير النماذج المثالة.

class Foo(db.Model): bars = db.ListProperty(db.Key)

class Bar(db.Model): pass

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

related_foos = Foo.all().filter('bars', bar_entity).fetch(fetch_count) 

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

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

المحلول

بالنظر إلى سجل فو يحتوي على 10 bar_entities والبحث عن جميع سجلات فو التي لديها ما لا يقل عن 2 من هذه الكيانات العشر ستؤدي إلى 45 قيم المساواة المحتملة 10! / (2! * (10-2)!) = 45.

يمكن استنتاج ذلك في 10_c_ (2-1) = 10 يقرأ.

SELECT * from table WHERE bar="1" AND bar in ["2", "3", "4", "5", "6", "7", "8", "9", "0"]
SELECT * from table WHERE bar="2" AND bar in ["3", "4", "5", "6", "7", "8", "9", "0"]
SELECT * from table WHERE bar="3" AND bar in ["4", "5", "6", "7", "8", "9", "0"]
etc.

لتقليل ذلك إلى قراءة واحدة سيتطلب ذلك عند إضافة سجل FOO، تقوم بتعبئة جدول منفصل يحتوي على جميع المجموعات 2 للحصول على سجل معين.

Say you had

foo_table
foo1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
foo2 [1, 3, 4]
foo3 [1, 2, a]
foo4 [b, 6, c]

foo_combo_2_table
Parent  Combination
foo1    12
foo1    13
... and all 45 foo1 combinations each in its own row
foo2    13
foo2    14
foo2    34
foo3    12
foo3    1a
foo3    2a
etc.

Now you can do a 

indexes = SELECT __KEY__ from foo_combo_2_table WHERE combination IN [12, 13, 14, 15, ... all 45]
keys = [k.parent() for k in indexes] # you would need to filter for duplicates

وبهذه الطريقة لن تدخل في أي مشكلات فهرس تنفجر.

إذا كنت ترغب أيضا في القيام بأي كيانات 3 أو أي 4 من كل من كل منها، فستحتاج إلى إنشاء عدد من القراءات Foo_Combo_n_table أو القيام بعمل 10_c_ (N-1) من القراءات.

نصائح أخرى

يمكنك ببساطة تطبيق نفس المرشح بشكل متكرر:

related_foos = Foo.all().filter('bars', bar_entity).filter('bars', bar_entity_2).fetch(fetch_count)

أو، مدفوعة البيانات:

q = Foo.all()
for bar in bar_entities:
  q.filter('bars', bar)
related_foos = q.fetch(fetch_count)

إذا لم تقم بتطبيق أي عدم المساواة أو ترتيب الطلبات إلى الاستعلام، فسيتمكن DataStore من تنفيذ الاستعلامات باستخدام الفهارس المدمجة واستراتيجية الانضمام إلى دمج، بغض النظر عن عدد المرشحات التي تطبقها. إذا كنت بحاجة إلى عدم المساواة أو ترتيب الفرز، فستحتاج إلى أن يكون لديك فهرس لكل عدد من الأشرطة التي قد ترغب في التصفية، مما يؤدي إلى انفجار الفهارس (وهكذا يتم تجنبه بشكل أفضل!)

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