9

से मेल खाने वाले आइटमों का एक पृष्ठ/आइटम गिनती/नेविगेशन प्रदान करने के लिए विचार/विकल्प ढूंढना मुझे डेटास्टोर सादगी, मापनीयता और उपयोग में आसानी पसंद है; और नए ndb लाइब्रेरी में पाए गए एन्हांसमेंट शानदार हैं।GAE डेटास्टोर क्वेरी

जैसा कि मैं डेटास्टोर सर्वोत्तम प्रथाओं को समझता हूं, किसी को प्रश्न पूछने वाले आइटम की संख्या और/या पृष्ठ क्वेरी की गणना करने के लिए कोड नहीं लिखना चाहिए जब क्वेरी से मेल खाने वाली वस्तुओं की संख्या बड़ी होती है; क्योंकि ऐसा करने का एकमात्र तरीका संसाधनों को गहन करने वाले सभी परिणामों को पुनर्प्राप्त करना है।

हालांकि, हमारे सहित कई अनुप्रयोगों में, मिलान करने वाली वस्तुओं की गिनती देखने और उपयोगकर्ता को उन परिणामों के एक विशिष्ट पृष्ठ पर नेविगेट करने की क्षमता प्रदान करने की एक आम इच्छा है। Paging Through Large Datasets आलेख में उल्लिखित अनुसार fetch (सीमा, ऑफ़सेट = एक्स) की सीमाओं के आसपास काम करने की आवश्यकता से डेटास्टोर पेजिंग समस्या अधिक जटिल है। अनुशंसित दृष्टिकोण का समर्थन करने के लिए, डेटा में एक विशिष्ट मूल्यवान कॉलम शामिल होना चाहिए जिसे परिणामों को प्रदर्शित करने के तरीके में आदेश दिया जा सकता है। यह कॉलम परिणामों के प्रत्येक पृष्ठ के लिए प्रारंभिक मान परिभाषित करेगा; इसे सहेजते हुए, हम इसी पृष्ठ को कुशलता से प्राप्त कर सकते हैं, जिससे नेविगेशन को अनुरोध के अनुसार एक विशिष्ट या अगले पृष्ठ पर अनुमति मिलती है। इसलिए, यदि आप कई तरीकों से आदेशित परिणाम दिखाना चाहते हैं, तो ऐसे कई स्तंभों को बनाए रखने की आवश्यकता हो सकती है।

यह ध्यान दिया जाना चाहिए कि एसडीके v1.3.1, Query Cursors के रूप में डेटास्टोर पेजिंग करने का अनुशंसित तरीका है। इनकी कुछ सीमाएं हैं, जिनमें IN और! = फ़िल्टर ऑपरेटर के लिए समर्थन की कमी शामिल है। वर्तमान में हमारे कुछ महत्वपूर्ण प्रश्न में उपयोग करते हैं, लेकिन हम क्वेरी कर्सर के उपयोग के लिए या का उपयोग करके उन्हें लिखने का प्रयास करेंगे।

दिशा निर्देशों का सुझाव दिया के बाद, एक उपयोगकर्ता एक (अगला) और (पिछला) नेविगेशन बटन, साथ ही विशेष पृष्ठ बटन के रूप में नेविगेशन दीं दिया जा सकता। उदाहरण के लिए यदि उपयोगकर्ता (अगला) दबाकर 3 बार दबाता है, तो ऐप नेविगेशन कुशल रखने के लिए प्रत्येक के लिए अद्वितीय प्रारंभिक रिकॉर्ड या कर्सर को याद करते हुए निम्न बटन दिखा सकते हैं: (पिछला) (पृष्ठ -1) (पृष्ठ -2) (पेज -3) (पेज -4) (अगला)

कुछ ने अलग-अलग मामलों का ट्रैक रखने का सुझाव दिया है, लेकिन यह दृष्टिकोण व्यावहारिक नहीं है जब उपयोगकर्ताओं को उन क्षेत्रों के समृद्ध सेट पर पूछने की अनुमति दी जाएगी जो परिणाम लौटाएंगे।

मैं सामान्य रूप में इन मुद्दों पर अंतर्दृष्टि और विशेष रूप से निम्न प्रश्नों के लिए देख रहा हूँ: अपने डेटासंग्रह क्षुधा में

  1. नौवहन क्या क्वेरी परिणामों के विकल्प आप प्रदान करते हैं इन सीमाओं को हल करने के लिए?

  2. तो कुशल परिणाम मायने रखता है और पेज संपूर्ण क्वेरी परिणाम सेट के नेविगेशन के साथ उपयोगकर्ताओं को उपलब्ध कराने के एक प्राथमिकता है, डेटा स्टोर का उपयोग करना चाहिए GAE MySql solution अब पेशकश की जा रही के पक्ष में छोड़ दिया जाना।

  3. क्या बड़े टेबल आर्किटेक्चर या डेटास्टोर कार्यान्वयन में कोई आगामी बदलाव है जो के लिए अतिरिक्त क्षमता प्रदान करेगा, जो एक प्रश्न के कुशलतापूर्वक परिणाम की गणना कर रहा है?

आपकी सहायता के लिए अग्रिम धन्यवाद।

उत्तर

2

यह सब इस बात पर निर्भर करता है कि आप आमतौर पर कितने परिणाम प्राप्त करते हैं। जैसे .count() को पास करके एक उपयुक्त सीमा है यदि आप #items उदा। < = 100 और "बहुत" यदि अधिक हैं। ऐसा लगता है कि आप सभी संभावित गणनाओं की पूर्व गणना नहीं कर सकते हैं, लेकिन कम से कम आप उन्हें कैश कर सकते हैं, जिससे कई डेटास्टोर सेशन बचा सकते हैं।

एनडीबी का उपयोग करके, सबसे कुशल दृष्टिकोण fetch_page() का उपयोग करके इकाइयों के पहले पृष्ठ का अनुरोध करने के लिए हो सकता है, और फिर परिणामस्वरूप कर्सर का उपयोग गिनती() कॉल के लिए प्रारंभिक बिंदु के रूप में कर सकता है; या वैकल्पिक रूप से, आप पहले पृष्ठ के fetch() को चलाने से बेहतर हो सकते हैं और गिनती() समवर्ती रूप से इसकी एसिंक सुविधाओं का उपयोग कर सकते हैं। दूसरा विकल्प आपकी एकमात्र पसंद हो सकता है यदि आपकी क्वेरी कर्सर का समर्थन नहीं करती है। अधिकांश IN/OR क्वेरी वर्तमान में कर्सर का समर्थन नहीं करते हैं, लेकिन यदि आप __key__ द्वारा ऑर्डर करते हैं तो वे करते हैं।

UI विकल्पों के संदर्भ में, मुझे लगता है कि यह अगले और पिछले पृष्ठ विकल्पों की पेशकश करने के लिए पर्याप्त है; "Gooooooogle" UI जो कई पृष्ठों को छोड़ने का समर्थन करता है वह प्यारा है लेकिन मैं इसे लगभग कभी भी उपयोग नहीं करता हूं। ("पिछले पृष्ठ" को लागू करने के लिए, क्वेरी के क्रम को उलट दें और उसी पृष्ठ का उपयोग करें जिसका उपयोग आपने वर्तमान पृष्ठ के लिए किया था। मुझे यकीन है कि यह काम करने की गारंटी है।)

+0

मान लीजिए कि हम उपयोगकर्ता को "1-20 का सी" या "1-20 में से कई को दिखाने के लिए सी = query.count (N) दृष्टिकोण का उपयोग करते हैं, हम अपने उपयोग में एन के लिए उचित मूल्य, लागत के अनुसार कैसे निर्धारित करते हैं। मामला 100 बहुत छोटा होगा। इस पर कोई सुझाव है कि इसका मूल्य $ कम रखने के लिए सबसे अच्छा कैसे किया जाए? एनडीबी दस्तावेज़ों से: "ध्यान दें कि गिनती(), जबकि fetch() से तेज़ है, तब भी जब भी इसे कॉल किया जाता है तो बहुत सारे काम करता है "कितना कोटा उपयोग किया जाता है? गुइडो, पायथन, एनडीबी और आपकी मदद के लिए धन्यवाद :) आईएमओ पेज मायने रखता है और नौसेना कुछ ऐप्स के लिए एक अच्छी सुविधा है क्योंकि उपयोगकर्ता अपने पैरा से मेल खाने वाले डेटा के आकार का मूल्यांकन और समायोजन कर सकते हैं ड्रिलिंग से पहले –

+1

आप इस पृष्ठ का उपयोग कर लागत की गणना कर सकते हैं: http://code.google.com/appengine/docs/billing.html#Billable_Resource_Unit_Costs। AFAIK एक गणना() एक कुंजी-केवल क्वेरी की तरह है। कैशिंग पर विचार करें मायने रखता है। (समर्थक के आधार पर ब्लेम, यदि आपके पास कैश की सीमित संख्या है, तो आप sharded-counter पैटर्न का उपयोग करके डेटास्टोर में गिनती स्टोर कर सकते हैं।) –

+3

आईएन/या क्वेरी पर भी एक अपडेट: आप किसी भी क्वेरी को कर्सर में बदल सकते हैं मौजूदा सॉर्ट ऑर्डर के अंत में __key__ द्वारा ऑर्डरिंग जोड़कर क्वेरी का समर्थन करना। जैसे एनडीबी में: 'कर्मचारी.क्यूरी (कर्मचारी.नाम.आईएन (['जो', 'जेन'])) आदेश (कर्मचारी। नाम, कर्मचारी.की) .fetch_page (एन)' - कर्मचारी.की आदेश के बिना यह BadArgumentError उठाता है। –

0
  1. मैं देखा कि जीमेल कुछ मायने रखता है के साथ तैयार है - यह आप बता सकते हैं कि आप कितने कुल ईमेल प्राप्त हो गया है, और कितने अपने इनबॉक्स में आदि कर रहे हैं, - लेकिन अन्य मायने रखता है, पूर्ण-पाठ की तरह पर यह खोज कहते हैं कि आप "कई में से 1-20" या "लगभग 130 में से 1-20" देख रहे हैं। क्या आपको वास्तव में प्रत्येक क्वेरी के लिए गणना प्रदर्शित करने की आवश्यकता है, या आप केवल महत्वपूर्ण लोगों की गणना कर सकते हैं?
+0

अच्छी तरह से ज्ञात योग का ट्रैक रखना निश्चित रूप से आसान है। कुछ लेखों में मैंने लोगों को GAE पर इसके लिए sharded काउंटर का उपयोग किया है: http://code.google.com/appengine/articles/sharding_counters.html। हमारा उपयोग केस जीमेल पूर्ण-पाठ खोजों के समान ही है। मुझे लगता है कि कुल योग और पृष्ठ नेविगेशन उपयोगकर्ताओं को उनके खोज परिणामों की बेहतर समझ के साथ उपयोगकर्ताओं को ड्रिल करने से पहले प्रदान करता है। ऐसा कहा जाता है कि ऐसा लगता है कि कोई डेटास्टोर का उपयोग करता है, केवल एक ही विकल्प है यहां कुछ खुलासे को छोड़कर "1-20 में से कई" दृष्टिकोण। संभवतः जीमेल "130 के 1-20" दिखाता है जब परिणाम सेट छोटा होता है, शायद आगे देखो। –

1

शायद पेजिंग की इस शैली का लक्ष्य :

(प्रथम) (पिछला) (पृष्ठ 1) (पृष्ठ 2) (पृष्ठ 3) .... (अंतिम) (अगले)

इस तरह कुल संख्या की आवश्यकता नहीं है - आप केवल अपने कोड की जरूरत यह जानने के लिए कि एक और 3+ पृष्ठों के लिए पर्याप्त परिणाम हैं। प्रति पेज 10 आइटम के पेज आकार के साथ, आपको केवल 30+ आइटम हैं जानने की आवश्यकता है।

यदि आपके पास 60 आइटम हैं, (6 पृष्ठों के लिए पर्याप्त) जब आप पहले से ही पेज 4 पर हैं, तो आपका कोड आगे देखेगा और महसूस होगा कि वहां केवल 20 अन्य रिकॉर्ड हैं, ताकि आप अंतिम पृष्ठ संख्या दिखा सकें:

(प्रथम) (पिछला) (Page4) (Page5) (Page6) (अगले) (अंतिम)

मूल रूप से प्रत्येक के लिए वर्तमान पृष्ठ के लिए लाने के लिए, बस डेटा का एक और 3 पृष्ठों के लिए पर्याप्त रिकॉर्ड लाने, उन्हें यह देखने के लिए गिनें कि आपके पास कितने अधिक पृष्ठ हैं, फिर तदनुसार अपने पेजर को हटा दें।

इसके अलावा, अगर आप केवल चाबियाँ लाते हैं, तो यह अतिरिक्त वस्तुओं को लाने से अधिक कुशल होगा। उम्मीद है कि कुछ समझ में आता है !!?? :)

+0

अरे @ जो सुझाव के लिए धन्यवाद। आपने मेरे मूल प्रश्न के 5 वें अनुच्छेद में ऊपर वर्णित किए गए कार्यों को पकड़ लिया है। Guido का जवाब क्या संभव है पर ध्यान केंद्रित करता है। गिनती क्वेरी की लागत को देखते हुए, एक बड़े डेटासेट के लिए हम निश्चित रूप से "..." जैसे कुछ का उपयोग करेंगे जब एन परिणामों की कुल संख्या से छोटा होगा। अधिक संदर्भ के लिए गिडो के उत्तर के तहत चर्चा देखें। –

0

चूंकि सवाल "पृष्ठ प्रदान करने के लिए विचारों/विकल्पों की तलाश में था", शायद कुंजी पेजों के 10 पृष्ठों के लायक होने का बहुत ही सरल विकल्प, फिर इस सेट के भीतर नेविगेशन को संभालने पर विचार करना उचित है।

Backward pagination with cursor is working but missing an item

नमूना कोड इस प्रश्न के लिए अधिक उपयुक्त होगा:

मैं एक ऐसी ही सवाल का जवाब देने में इस पर सविस्तार है, तो आप वहाँ नमूना कोड मिल जाएगा।

def session_list(): 
    page = request.args.get('page', 0, type=int) 

    sessions_keys = Session.query().order(-Session.time_opened).fetch(100, keys_only=True) 
    sessions_keys, paging = generic_list_paging(sessions_keys, page) 
    # generic_list_paging will select the proper sublist. 
    sessions = [ sk.get() for sk in sessions_keys ] 

    return render_template('generic_list.html', objects=sessions, paging=paging) 

अधिक कोड के लिए संदर्भित प्रश्न देखें: यहाँ यह का एक टुकड़ा है।

बेशक, यदि परिणाम सेट संभावित रूप से विशाल है, तो लाने के लिए कुछ सीमा अभी भी दी जानी चाहिए, हार्ड सीमा 1000 आइटम है जो मुझे लगता है। जाहिर है, यह परिणाम कुछ 10 पृष्ठों से अधिक लंबा है, उपयोगकर्ता को मानदंड जोड़कर परिष्कृत करने के लिए कहा जाएगा।

कुछ सैकड़ों कुंजी के भीतर पेजिंग के साथ लेन-देन करना वास्तव में बहुत आसान है, यह निश्चित रूप से विचार करने योग्य है। यह प्रश्न में उल्लिखित प्रत्यक्ष पृष्ठ नेविगेशन प्रदान करना काफी आसान बनाता है। वास्तविक इकाई आइटम केवल वास्तविक वर्तमान पृष्ठ के लिए लाए जाते हैं, बाकी केवल कुंजी हैं इसलिए यह इतना महंगा नहीं है। और आप कुछ मिनटों के लिए memcache में key_only परिणाम सेट रखने पर विचार कर सकते हैं ताकि उपयोगकर्ता तुरंत पृष्ठों के माध्यम से ब्राउज़ करने के लिए एक ही क्वेरी को फिर से करने की आवश्यकता न हो।

संबंधित मुद्दे