2013-02-12 28 views
5

मैं निम्नलिखित की तरह एक दस्तावेज़ संरचना है:RavenDb स्थिर सूचकांक: बच्चे संग्रह पर क्वेरी वस्तुओं

Employer => Positions => RequiredSkills

नियोक्ता स्थिति
पदों RequiredSkill का एक संग्रह है का संग्रह है।
आवश्यक कौशल में एक कौशल (स्ट्रिंग) और एक प्रवीणता (enum) शामिल है।

यदि मैं एक गतिशील सूचकांक का उपयोग करता हूं तो ऐसा लगता है कि कंपनी ठीक है, हालांकि मैं यूआई में वापस आने के लिए एमवीसी व्यू मॉडल को पॉप्युलेट करने के लिए एक इंडेक्स का उपयोग करना चाहता हूं।

मैं वास्तव में रेवेन के लिए नया हूं इसलिए बेवकूफ/अनावश्यक कुछ करने के लिए मेरी माफ़ी!

public class PositionSearch : AbstractIndexCreationTask<Employer> 
    { 
     public PositionSearch() 
     { 
      Map = employers => 
        from employer in employers 
        from position in employer.Positions 
        select new 
         { 
          EmployerId = employer.Id, 
          EmployerName = employer.Name, 
          PositionId = position.Id, 
          PositionTitle = position.Title, 
          position.Location, 
          position.Description, 
          RequiredSkills = position.RequiredSkills 
         }; 

      StoreAllFields(FieldStorage.Yes); 

      Index("RequiredSkills_Skill", FieldIndexing.Analyzed); 
     } 
    } 

हालांकि जब मैं निम्न क्वेरी को निष्पादित करने का प्रयास करें::

var results = session.Query<PositionSearchResultModel, PositionSearch>() 
    .Customize(x => x.WaitForNonStaleResults()) 
    .Where(x=>x.RequiredSkills.Any(y=>y.Skill == "SkillName")) 
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>() 
    .ToList(); 

मैं निम्नलिखित त्रुटि मिलती है:

System.ArgumentException: 
    The field 'RequiredSkills_Skill' is not indexed, 
    cannot query on fields that are not indexed 

कर सकते हैं

मैं निम्नलिखित मानचित्रण मिल गया है कोई भी देखता है कि मैं क्या गलत कर रहा हूं या कृपया मेरे लिए एक और दृष्टिकोण सुझा सकता हूं?

धन्यवाद,

जेम्स

अद्यतन मेरे विचार मॉडल - धन्यवाद:

public class PositionSearchResultModel 
{ 
    public PositionSearchResultModel() 
    { 
     RequiredSkills = new HashSet<SkillProficiency>(); 
    } 

    public string EmployerId { get; set; } 
    public string EmployerName { get; set; } 
    public string PositionId { get; set; } 
    public string PositionTitle { get; set; } 
    public string Location { get; set; } 
    public string Description { get; set; } 
    public ICollection<SkillProficiency> RequiredSkills { get; set; } 
} 
+0

आप इंडेक्स परिणामों के साथ इंडेक्स प्रविष्टियों को भ्रमित कर रहे हैं। कृपया अपना 'PositionSearchResultModel' क्लास प्रदान करें और मैं एक पूर्ण समाधान के साथ जवाब दूंगा। धन्यवाद। –

+0

मेरा दृश्य मॉडल जोड़ा गया। – Jamez

+0

मुझे लगता है कि आप क्षेत्र के रूप में चिह्नित करने की कोशिश कर रहे थे। क्या आप कौशल नाम पर एक सटीक मैच चाहते हैं? या आप एक विश्लेषण खोज करना चाहते थे? –

उत्तर

8

क्योंकि आप कौशल नाम के खिलाफ एक विश्लेषण किया खोज करना चाहते हैं, तो आप के रूप में यह अलग-थलग करने की जरूरत है एक अलग इंडेक्स प्रविष्टि।

public class PositionSearch 
    : AbstractIndexCreationTask<Employer, PositionSearchResultModel> 
{ 
    public PositionSearch() 
    { 
     Map = employers => 
       from employer in employers 
       from position in employer.Positions 
       select new 
       { 
        EmployerId = employer.Id, 
        EmployerName = employer.Name, 
        PositionId = position.Id, 
        PositionTitle = position.Title, 
        position.Location, 
        position.Description, 
        position.RequiredSkills, 

        // Isolate the search property into it's own value 
        SkillsSearch = position.RequiredSkills.Select(x => x.Skill) 
       }; 

     // you could store all fields if you wanted, but the search field 
     // doesn't need to be stored so that would be wasteful. 
     Store(x => x.PositionId, FieldStorage.Yes); 
     Store(x => x.PositionTitle, FieldStorage.Yes); 
     Store(x => x.Location, FieldStorage.Yes); 
     Store(x => x.Description, FieldStorage.Yes); 
     Store(x => x.RequiredSkills, FieldStorage.Yes); 

     // Any field you are going to use .Search() on should be analyzed. 
     Index(x => x.SkillsSearch, FieldIndexing.Analyzed); 
    } 
} 

ध्यान दें कि मैंने सूचकांक के परिणाम के रूप में प्रक्षेपण निर्दिष्ट किया है। यह वाक्य रचनात्मक चीनी है। इसे छोड़ना गलत नहीं है, लेकिन फिर आपको स्ट्रिंग का उपयोग करके अपना खोज फ़ील्ड निर्दिष्ट करना होगा।

तुम भी अपने परिणामों वर्ग

public string[] SkillsSearch { get; set; } 

यह वास्तव में कोई फर्क नहीं पड़ता यह है कि किस प्रकार के लिए खोज फ़ील्ड जोड़ने की आवश्यकता होगी। एक स्ट्रिंग सरणी या संग्रह ठीक काम करेगा। आप केवल एक स्ट्रिंग या ऑब्जेक्ट का उपयोग भी कर सकते हैं, क्योंकि यह केवल वह नाम है जो प्रासंगिक है।

जब आप इस सूचकांक के खिलाफ क्वेरी, इस तरह, .Search() विधि का उपयोग करें: एकमात्र कारण आप इतने सारे क्षेत्रों स्टोर करने के लिए किया है

var results = session.Query<PositionSearchResultModel, PositionSearch>() 
    .Customize(x => x.WaitForNonStaleResults()) // only use this in testing 
    .Search(x=> x.SkillsSearch, "SkillName") 
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>() // AsProjection would also work 
    .ToList(); 

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

+0

मुझे ऐसा कुछ करने की ज़रूरत है, लेकिन मुझे परिणाम देखने की आवश्यकता नहीं है, बस जांचें कि कोई कौशल मौजूद है या नहीं। क्या इसका मतलब है कि मुझे उन क्षेत्रों को स्टोर करने की आवश्यकता नहीं है? – codedog

+1

@DanyW - यदि आप केवल उस खंड में फ़ील्ड्स का उपयोग कर रहे हैं, तो आपको उन्हें स्टोर करने की आवश्यकता नहीं है। यदि आप उन्हें अपने परिणाम सेट पर वापस पेश करने जा रहे हैं तो उन्हें केवल तभी संग्रहीत करने की आवश्यकता है। –