2012-04-06 3 views
26
साथ

मैं जानता हूँ कि इस सवाल के वेरिएंट से पहले (यहां तक ​​कि मेरे द्वारा) कहा गया है, लेकिन मैं अभी भी एक बात या इस बारे में दो समझ में नहीं आता रास्ता ...उचित से अधिक 128 दस्तावेज़ पुन: प्राप्त करने के लिए RavenDB

यह मेरी समझ है कि एक ऐसा करके 128 डिफ़ॉल्ट सेटिंग की तुलना में अधिक दस्तावेजों को पुनः प्राप्त कर सकता था:

session.Advanced.MaxNumberOfRequestsPerSession = int.MaxValue; 

और मैंने सीखा है कि कहां खंड, एक समारोह के बजाय एक ExpressionTree होना चाहिए ताकि यह Queryable के रूप में देखा जाता है बजाय एक संख्यात्मक इसलिए मैंने सोचा कि यह काम करना चाहिए:

public static List<T> GetObjectList<T>(Expression<Func<T, bool>> whereClause) 
{ 
    using (IDocumentSession session = GetRavenSession()) 
    { 
     return session.Query<T>().Where(whereClause).ToList();     
    } 
} 

हालांकि, यह केवल 128 दस्तावेज़ लौटाता है। क्यूं कर?

ध्यान दें, यहाँ कोड है कि ऊपर प्रणाली को बुलाती है:

RavenDataAccessComponent.GetObjectList<Ccm>(x => x.TimeStamp > lastReadTime); 

अगर मैं टेक (एन) जोड़ने के लिए, तो मैं के रूप में मुझे पसंद के रूप में कई दस्तावेजों प्राप्त कर सकते हैं। उदाहरण के लिए, इस 200 दस्तावेज प्रस्तुत करती है:

return session.Query<T>().Where(whereClause).Take(200).ToList(); 

इस सब के आधार पर यह प्रतीत होता है दस्तावेजों के हजारों पुनः प्राप्त करने के उचित तरीके से MaxNumberOfRequestsPerSession सेट और क्वेरी में लें() का उपयोग करने के लिए है कि। क्या वह सही है? यदि नहीं, तो यह किया जाना चाहिए?

मेरे ऐप के लिए, मुझे हजारों दस्तावेज़ पुनर्प्राप्त करने की आवश्यकता है (जिनमें उनमें बहुत कम डेटा है)। हम इन दस्तावेज़ों को स्मृति में रखते हैं और चार्ट के लिए डेटा स्रोत के रूप में उपयोग करते हैं।

** संपादित करें **

मैं अपने लें() में int.MaxValue उपयोग करने की कोशिश:

return session.Query<T>().Where(whereClause).Take(int.MaxValue).ToList(); 

और वह 1024 अरे देता है। मैं 1024 से अधिक कैसे प्राप्त करूं?

** संपादित करें 2 - नमूना दस्तावेज़ दिखा डेटा **

{ 
    "Header_ID": 3525880, 
    "Sub_ID": "120403261139", 
    "TimeStamp": "2012-04-05T15:14:13.9870000", 
    "Equipment_ID": "PBG11A-CCM", 
    "AverageAbsorber1": "284.451", 
    "AverageAbsorber2": "108.442", 
    "AverageAbsorber3": "886.523", 
    "AverageAbsorber4": "176.773" 
} 
+0

क्या आप एक दस्तावेज़ के अंदर सभी 10000 अंक एक संग्रह के रूप में डालने के बारे में सोचते थे? – SteadyEddi

उत्तर

20

Take(n) समारोह केवल आप 1024 डिफ़ॉल्ट रूप से दे देंगे। हालांकि, अगर आप Raven.Server.exe.config में यह डिफ़ॉल्ट बदल सकते हैं:

<add key="Raven/MaxPageSize" value="5000"/> 

अधिक जानकारी के लिए, देखें: http://ravendb.net/docs/intro/safe-by-default

+0

धन्यवाद, माइक। मुझे लगता है कि यह स्वीकार किए गए उत्तर को समाप्त कर देगा, लेकिन मैं देखना चाहता हूं कि किसी और के पास इस पर एक अलग कोण है या नहीं। –

5

प्रति सत्र अनुरोध की संख्या तो प्रति कॉल पुनः प्राप्त दस्तावेजों की संख्या एक अलग अवधारणा है। सत्र कम रहते हैं और उनसे कुछ कॉल जारी होने की उम्मीद है।

यदि आप मानव उपभोग के लिए दुकान से कुछ भी 10 (डिफ़ॉल्ट रूप से डिफ़ॉल्ट 128) प्राप्त कर रहे हैं तो कुछ गलत है या आपकी समस्या को अलग-अलग सोच की आवश्यकता है, फिर डेटा स्टोर से आने वाले दस्तावेज़ों के ट्रक लोड।

रावेनडीबी इंडेक्सिंग काफी परिष्कृत है। here अनुक्रमणित करने के बारे में अच्छा लेख और पहलू here

यदि आपको डेटा एकत्रीकरण करने की आवश्यकता है, तो मानचित्र बनाएं/इंडेक्स को कम करें जिसके परिणामस्वरूप समेकित डेटा शामिल है।:

सूचकांक:

from post in docs.Posts 
    select new { post.Author, Count = 1 } 

    from result in results 
    group result by result.Author into g 
    select new 
    { 
     Author = g.Key, 
     Count = g.Sum(x=>x.Count) 
    } 

क्वेरी:

session.Query<AuthorPostStats>("Posts/ByUser/Count")(x=>x.Author)(); 
+1

तो आप इस मुद्दे को कैसे हल करेंगे? व्यवसाय पिछले 24 घंटों के डेटा पॉइंट्स दिखाने वाले चार्ट को देखना चाहता है। प्रत्येक दस्तावेज़ एक डेटा बिंदु है, और पिछले 24 घंटों में से 10,000 में से हैं। आप सभी डेटा को लाए बिना चार्ट कैसे करते हैं? –

+0

मुझे लगता है कि आप इंडेक्स या [facets] (http://ravendb.net/docs/client-api/faceted-search) –

+0

बनाकर इसे प्राप्त कर सकते हैं मैंने अभी देखा है "प्रत्येक दस्तावेज़ एक डेटा पॉइंट है" - क्या आप इस दस्तावेज़ का एक उदाहरण दिखाओ? –

16

लें (एन) समारोह केवल आप 1024 डिफ़ॉल्ट रूप से दे देंगे। हालांकि, अगर आप यह जोड़ी में साथ छोड़ें (एन) सभी

 var points = new List<T>(); 
     var nextGroupOfPoints = new List<T>(); 
     const int ElementTakeCount = 1024; 
     int i = 0; 
     int skipResults = 0; 

     do 
     { 
      nextGroupOfPoints = session.Query<T>().Statistics(out stats).Where(whereClause).Skip(i * ElementTakeCount + skipResults).Take(ElementTakeCount).ToList(); 
      i++; 
      skipResults += stats.SkippedResults; 

      points = points.Concat(nextGroupOfPoints).ToList(); 
     } 
     while (nextGroupOfPoints.Count == ElementTakeCount); 

     return points; 

RavenDB Paging

+1

यह विधि अब तक बेहतर दृष्टिकोण है। – Matt

+4

सर्वर अनुरोधों की संख्या पर सीमा से सावधान रहें। रावेन के "डिफ़ॉल्ट रूप से सुरक्षित" सेटिंग्स के अनुसार, यह केवल सर्वर के लिए 30 राउंड-ट्रिप कर देगा, इसलिए यदि लूप को उससे अधिक निष्पादित करने की आवश्यकता है, तो यह विफल हो जाएगा क्योंकि लूप का प्रत्येक पुनरावृत्ति एक और सर्वर अनुरोध है। टिप के लिए –

34

यह ध्यान देने योग्य है कि संस्करण 2.5 के बाद से, RavenDB एक "असीम परिणाम एपीआई" स्ट्रीमिंग अनुमति देने के लिए है लायक है पाने के लिए उपयोग कर सकते हैं। डॉक्स से उदाहरण से पता चलता है कि यह कैसे उपयोग करने के लिए:

var query = session.Query<User>("Users/ByActive").Where(x => x.Active); 
using (var enumerator = session.Advanced.Stream(query)) 
{ 
    while (enumerator.MoveNext()) 
    { 
     User activeUser = enumerator.Current.Document; 
    } 
} 

मानक RavenDB प्रश्नों, Lucence प्रश्नों के लिए समर्थन नहीं है और वहाँ भी async समर्थन है।

प्रलेखन here पाया जा सकता है। Ayende का प्रारंभिक ब्लॉग आलेख here पाया जा सकता है।

+1

+1। धन्यवाद! –

+3

सावधान रहें कि स्ट्रीमिंग API का उपयोग करते समय पूछताछ करते समय, अनुक्रमणिका पहले से मौजूद होनी चाहिए। यदि आप सामान्य सत्र API के माध्यम से कोई क्वेरी चलाते हैं, और कोई मिलान सूचकांक मौजूद नहीं है, तो एक गतिशील अनुक्रमणिका बनाई जाएगी। लेकिन स्ट्रीमिंग एपीआई में, डायनामिक इंडेक्स नहीं बनाया गया है और सर्वर शिकायत करता है कि इंडेक्स नहीं मिला है। –

+0

माइक - यह दिलचस्प व्यवहार है, यह एक बग की तरह लगता है। क्या आपने रावेनडीबी समूह में इस पर चर्चा की है? –

0

आप Stream विधि के साथ पूर्वनिर्धारित अनुक्रमणिका का भी उपयोग कर सकते हैं। आप अनुक्रमित क्षेत्रों पर एक खंड का उपयोग कर सकते हैं।

var query = session.Query<User, MyUserIndex>(); 
var query = session.Query<User, MyUserIndex>().Where(x => !x.IsDeleted); 

using (var enumerator = session.Advanced.Stream<User>(query)) 
{ 
    while (enumerator.MoveNext()) 
    { 
     var user = enumerator.Current.Document; 
     // do something 
    } 
} 

उदाहरण सूचकांक:

public class MyUserIndex: AbstractIndexCreationTask<User> 
{ 
    public MyUserIndex() 
    { 
     this.Map = users => 
      from u in users 
      select new 
      { 
       u.IsDeleted, 
       u.Username, 
      }; 
    } 
} 

प्रलेखन: What are indexes? Session : Querying : How to stream query results?


महत्वपूर्ण नोट: Stream विधि वस्तुओं को ट्रैक नहीं होगा। यदि आप इस विधि से प्राप्त वस्तुओं को बदलते हैं, तो SaveChanges() किसी भी बदलाव से अवगत नहीं होगा।


अन्य नोट: यदि आप उपयोग करने के लिए इंडेक्स निर्दिष्ट नहीं करते हैं तो आपको निम्न अपवाद मिल सकता है।

अमान्य ऑपरेशन अपवाद: स्ट्रीमक्वायर डायनामिक इंडेक्स क्वेरीिंग का समर्थन नहीं करता है। इसे बड़े डेटा-सेट के साथ उपयोग करने के लिए डिज़ाइन किया गया है और इंडेक्सिंग के 15 सेकंड के बाद सभी डेटा-सेट को वापस करने की संभावना नहीं है, जैसे क्वेरी() करता है।

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