2011-08-17 11 views
6

में एक से अधिक मान द्वारा एक बच्चे के संग्रह का पता कर रहा RavenDB 371 निर्माण का उपयोग कर रहा है और मैं निम्नलिखित मॉडल है:RavenDB

class Product { 
public string Id { get; set; } 
public ProductSpec[] Specs { get; set; } 
} 

class ProductSpec { 
public string Name { get; set; } 
public string Value { get; set; } 
} 

मैं उत्पादों जो चश्मा का एक सेट है के लिए क्वेरी करने के लिए सक्षम होने के लिए करना चाहते हैं। जब एक भी कल्पना से क्वेरी करने:

session.Query<Product>() 
.Where(product => product.Specs.Any(spec => spec.Name == "Color" && spec.Value == "Red")) 
.ToList(); 

की उम्मीद परिणाम नहीं दिए जाते हैं, लेकिन जब एक अतिरिक्त कल्पना विधेय जोड़ा जाता है:

कोई परिणाम नहीं दिए जाते हैं, भले ही पहले क्वेरी द्वारा रिटर्न परिणाम दिए spec नाम "देश" और spec मूल्य "यूएस" के साथ उत्पाद। LuceneQuery विधि का उपयोग करते समय एक ही परिणाम मनाया जाता है। यह this discussion पर एक समान समस्या प्रतीत होता है हालांकि मैं सुझाए गए समाधान को लागू करने में असमर्थ था। विशेष रूप से, सुझाए गए इंडेक्स बनाने के बाद, मुझे नहीं पता कि इसे कैसे पूछना है।

मैं रावेनडीबी में इस प्रकार की क्वेरी का समर्थन कैसे कर सकता हूं?

संपादित

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

class Product { 
public string Id { get; set; } 
public int CategoryId { get; set; } 
public string[] Specs { get; set; } 
} 

संदर्भ के लिए, मूल मॉडल और क्वेरी काम करता है जब उनके multikeys सूचकांक की सुविधा के साथ MongoDB का उपयोग कर। MongoDB के साथ बहुत ही आश्चर्यजनक समस्या यह है कि गिनती() ऑपरेशन slow for index queries है। इस प्रकार की क्वेरी पेजिनेशन के लिए आवश्यक है और हालांकि गिनती को कैश किया जा सकता है, मुझे एक समाधान चाहिए जो इसे बॉक्स से बाहर प्रदान करता है। साथ ही, मेरे पास एक अन्य आवश्यकता है जो उत्पादों के मनमाने ढंग से संग्रह के लिए स्पेक समूहों को एकत्रित करने की क्षमता है (उदाहरण के लिए, किसी दिए गए श्रेणी में उत्पादों के लिए सभी spec/value संयोजनों का संग्रह प्राप्त करने के लिए)। मोंगोडीबी में इसे अपनी मैड्रिडस कार्यक्षमता का उपयोग करके हासिल किया जा सकता है, हालांकि मैपरेडस ऑपरेशन के परिणाम स्थैतिक हैं और स्रोत डेटा में परिवर्तन होने पर मैन्युअल रूप से अपडेट किया जाना चाहिए जबकि रावेनडीबी पृष्ठभूमि में स्वचालित रूप से मैपरेडस इंडेक्स अपडेट करता है। इसलिए, हालांकि, रावेनडीबी में मैपरेडस इंडेक्स घोषित करना मोंगोडीबी आईएमओ में जितना बोझिल है, स्वचालित पृष्ठभूमि अपडेट लंबे शॉट से कमियों से अधिक है। मैं CouchDB देख रहा हूं क्योंकि उनके विचार स्वचालित रूप से अपडेट भी होते हैं, हालांकि ऐसा लगता है कि वे मांग पर अपडेट होते हैं, पृष्ठभूमि में स्वचालित रूप से नहीं, यह सुनिश्चित नहीं करते कि यह कोई समस्या होगी या नहीं।

+0

आप यहां इस को हल करने पर चर्चा देख सकते हैं: http://groups.google.com/group/ravendb/browse_thread/thread/dd8a77ccf7322c00/ab97561899624c47 –

+0

मुझे लगता है कि सुझाव मिल गया है समाधान स्ट्रिंग्स की सरणी जैसे सरल प्रकार के संग्रह के लिए काम करता है, लेकिन उत्पाद स्पीकर जैसे कंपाउंड प्रकार का काम नहीं करता है। क्वेरी समाप्त होने पर कोई परिणाम नहीं लौटाता है। – eulerfx

उत्तर

1

मैंने मॉडल को थोड़ा सा बदल दिया है और AbstractIndexCreationTask में प्रोजेक्ट विधि का उपयोग करके वांछित परिणाम प्राप्त करने में सक्षम था।

public class Products_ByCategoryIdAndSpecs_SortByTotalSold : AbstractIndexCreationTask<Product> 
{ 
    public Products_ByCategoryIdAndSpecs_SortByTotalSold() 
    { 
     this.Map = products => from product in products 
           select new 
           { 
            product.CategoryId, 
            _ = Project(product.Specs, spec => new Field("Spec_" + spec.Key, spec.Value, Field.Store.NO, Field.Index.ANALYZED)), 
            product.TotalSold 
           }; 
    } 
} 

तो मैं तो जैसे क्वेरी कर सकते हैं::

var results = session.Advanced.LuceneQuery<Product, Products_ByCategoryIdAndSpecs_SortByTotalSold>() 
     .WhereEquals("CategoryId", 15920) 
     .AndAlso().WhereEquals("Spec_Class", "3A") 
     .AndAlso().WhereEquals("Spec_Finish", "Plain") 
     .OrderBy("-TotalSold") 
     .ToList(); 

इस श्रेणी में उत्पादों वापस आ जाएगी

public class Product 
{ 
    public string Id { get; set; } 
    public int CategoryId { get; set; } 
    public int TotalSold { get; set; } 
    public Dictionary<string, string> Specs { get; set; } 
} 

यह सूचकांक परिभाषा है: यह (सरलीकृत) डेटा मॉडल है "15 9 20" जिसमें "3 ए" का "क्लास" स्पेक वैल्यू है और "प्लेन" का एक "फिनिश" स्पेक वैल्यू बेची गई कुल इकाइयों द्वारा अवरोही क्रम में क्रमबद्ध किया गया है।

कुंजी Project विधि का उपयोग कर रही थी जो मूल रूप से प्रत्येक spec नाम-मूल्य जोड़ी के लिए ल्यूसीन दस्तावेज़ में फ़ील्ड बनाता है।

3

मैंने अलग-अलग चीजों की कोशिश की है, और इसे या तो काम नहीं कर सका। आप जिस विशिष्ट क्वेरी को निष्पादित करने का प्रयास कर रहे हैं उसे RavenDB (संस्करण 426 में) द्वारा इस ल्यूसीन क्वेरी के लिए हल किया गया है:

"{(नाम: रंग और मूल्य: लाल) और (नाम: देश और मूल्य: यूएस)}" बताता है कि आपको कोई परिणाम क्यों नहीं मिलता है। Lucene Query Syntax

विभिन्न समाधानों जवाब में सुझाव दिया है:

विषय पर googling के बाद, मैं इस पोस्ट पाया। उम्मीद है कि यह मदद करेगा। हालांकि मैं खुद को उत्सुक हूं, अगर यह वास्तव में संभव नहीं है।

3

बिल्ड 717 के अनुसार आप मैट वॉरेन द्वारा किए गए नए .Intersect() सुविधा का उपयोग करके ऐसा कर सकते हैं। यहाँ एक नज़र डालें: http://issues.hibernatingrhinos.com/issue/RavenDB-51