2016-02-11 10 views
6

के साथ बहु फ़ील्ड मैपिंग सिंटैक्स के साथ इंडेक्स बनाएं I NEST 2.0 में बहु फ़ील्ड मैपिंग के लिए सिंटैक्स सही नहीं लग रहा है - अगर यह सही शब्दावली है। मैपिंग के लिए जो भी उदाहरण मिला है वह < = एनईटी का 1.x संस्करण प्रतीत होता है। मैं Elasticsearch और NEST के लिए नया हूं, और मैं उनके दस्तावेज पढ़ रहा हूं, लेकिन एनईएस दस्तावेज 2.x के लिए पूरी तरह से अद्यतन नहीं किया गया है।एनईटी 2.x

असल में, मुझे पूरे प्रकार को इंडेक्स या स्टोर करने की आवश्यकता नहीं है। कुछ फ़ील्ड जिन्हें मुझे केवल अनुक्रमण के लिए जरूरी है, कुछ फ़ील्ड मुझे इंडेक्स और पुनर्प्राप्त करने की आवश्यकता होगी, और कुछ को केवल पुनर्प्राप्ति के लिए अनुक्रमण की आवश्यकता नहीं है।

MyType 
{ 
    // Index this & allow for retrieval. 
    int Id { get; set; } 

    // Index this & allow for retrieval. 
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens. 
    string CompanyName { get; set; } 

    // Don't index this for searching, but do store for display. 
    DateTime CreatedDate { get; set; } 

    // Index this for searching BUT NOT for retrieval/displaying. 
    string CompanyDescription { get; set; } 

    // Nest this. 
    List<MyChildType> Locations { get; set; } 
} 

MyChildType 
{ 
    // Index this & allow for retrieval. 
    string LocationName { get; set; } 

    // etc. other properties. 
} 

मैं के रूप में किया जाता है का उपयोग कर एक उदाहरण के रूप में निम्नलिखित सूचकांक कर पाए संपूर्ण वस्तु और बच्चा है है:

client.Index(item, i => i.Index(indexName)); 

हालांकि, वास्तविक वस्तु इस की तुलना में बहुत बड़ा है , और मुझे वास्तव में इसकी अधिक आवश्यकता नहीं है। मुझे यह पता चला है, जो मुझे लगता है कि मैं क्या करना चाहता हूं, लेकिन एक पुराने संस्करण में: multi field mapping elasticsearch

मुझे लगता है कि "मैपिंग" वह है जो मैं जा रहा हूं, लेकिन जैसा कि मैंने कहा, मैं नया हूं Elasticsearch और NEST के लिए और मैं शब्दावली सीखने की कोशिश कर रहा हूँ।

नम्र रहो! :) एसओ पर एक प्रश्न पूछने का मेरा पहला समय है। धन्यवाद!

उत्तर

0

मुझे लगता है कि आप अपनी समस्या को हल करने के लिए कम से कम 2 संभावनाएं हैं:

  1. अनुक्रमण पर: एक मेटाडाटा मॉडल है, जो सिर्फ पुन: प्राप्त करने के लिए भंडारित किया जाता है की तरह कुछ बनाने के लिए। इस क्षेत्र में वापसी को सीमित करने के लिए _source field देखें।
  2. खोज पर: उन फ़ील्ड को निर्दिष्ट करें जिन्हें आप क्वेरी करना चाहते हैं: यदि आप CreateDate से पूछना नहीं चाहते हैं, तो बस इसे अपनी खोज में शामिल न करें।

मेरे मामले में मैं इन तरीकों का उपयोग कर रहा हूँ दोनों :-)

6

जहां तक ​​मैं देख सकता हूँ बहुत तेजी से परिणाम प्राप्त करने के, आप किसी भी जटिल प्रकार है कि आप नक्शे कोशिश कर रहे हैं नहीं है। तो आप अपनी वस्तुओं को मैप करने के लिए आसानी से एनईटी विशेषताओं का उपयोग कर सकते हैं।

चेक इस बाहर:

[Nest.ElasticsearchType] 
public class MyType 
{ 
    // Index this & allow for retrieval. 
    [Nest.Number(Store=true)] 
    int Id { get; set; } 

    // Index this & allow for retrieval. 
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens. 
    [Nest.String(Store = true, Index=Nest.FieldIndexOption.Analyzed, TermVector=Nest.TermVectorOption.WithPositionsOffsets)] 
    string CompanyName { get; set; } 

    // Don't index this for searching, but do store for display. 
    [Nest.Date(Store=true, Index=Nest.NonStringIndexOption.No)] 
    DateTime CreatedDate { get; set; } 

    // Index this for searching BUT NOT for retrieval/displaying. 
    [Nest.String(Store=false, Index=Nest.FieldIndexOption.Analyzed)] 
    string CompanyDescription { get; set; } 

    [Nest.Nested(Store=true, IncludeInAll=true)] 
    // Nest this. 
    List<MyChildType> Locations { get; set; } 
} 

[Nest.ElasticsearchType] 
public class MyChildType 
{ 
    // Index this & allow for retrieval. 
    [Nest.String(Store=true, Index = Nest.FieldIndexOption.Analyzed)] 
    string LocationName { get; set; } 

    // etc. other properties. 
} 

इस घोषणा के बाद, इस मानचित्रण elasticsearch में आप एक कॉल के समान बनाने की जरूरत है बनाने के लिए:

var mappingResponse = elasticClient.Map<MyType>(m => m.AutoMap()); 
Automap() के साथ

फोन घोंसला पढ़ा जाएगा कि आपके अपने पीओसीओ से गुण और तदनुसार मैपिंग अनुरोध बनाएं।

here से "विशेषता आधारित मानचित्रण" अनुभाग भी देखें।

चीयर्स!

3

लेखन के समय, Nest गुणों में निर्मित का उपयोग करके आपके दस्तावेज़ मैपिंग में कई कक्षाओं में अपनी कक्षा में किसी संपत्ति को मैप करने का कोई तरीका नहीं प्रदान करता है। हालांकि, यह आपके मैपिंग के साथ कुछ भी करने के लिए आवश्यक सुविधाएं प्रदान करता है जो आप कर सकते हैं यदि आप स्वयं JSON लिखते हैं।

यहां एक समाधान है जिसे मैंने अपनी आवश्यकताओं के लिए एक साथ रखा है। जो कुछ भी आपको करने की ज़रूरत है उसके लिए शुरुआती बिंदु के रूप में इसका उपयोग करना मुश्किल नहीं होना चाहिए।

सबसे पहले, यहाँ मानचित्रण मैं उत्पन्न करने के लिए

{ 
    "product":{ 
     "properties":{ 
     "name":{ 
      "type":"string", 
      "index":"not_analyzed", 
      "fields":{ 
       "standard":{ 
        "type":"string", 
        "analyzer":"standard" 
       } 
      } 
     } 
     } 
    } 
} 

product दस्तावेज़ तो name क्षेत्र है, जो अनुक्रमित है, लेकिन विश्लेषण किया नहीं होता चाहते हैं, और name.standard क्षेत्र है, जो मानक विश्लेषक का उपयोग करता है का एक उदाहरण है ।

सी # वर्ग है कि मैं इस तरह

[ElasticsearchType] 
public class Product 
{ 
    [WantsStandardAnalysisField] 
    public string Name { get; set; } 
} 

नोट WantsStandardAnalysisField विशेषता दिखता से मैपिंग। यह कोई विशेष गुण नहीं है जिसमें कोई विशेष गुण जोड़ा गया है। सचमुच:

public class WantsStandardAnalysisField : Attribute {} 

मैं Automap उपयोग करने के लिए के रूप में है, मेरे कस्टम विशेषता नजरअंदाज कर दिया जाएगा थे और मैं एक मानचित्रण name क्षेत्र है कि मिल जाएगा, लेकिन नहीं name.standard हैं। सौभाग्य से, ऑटोमैप IPropertyVisitor का एक उदाहरण स्वीकार करता है। NoopPropertyVisitor नामक एक बेस क्लास इंटरफ़ेस लागू करता है और कुछ भी नहीं करता है, इसलिए आप इसे उप-वर्गीकृत कर सकते हैं और केवल उन्हीं तरीकों को ओवरराइड कर सकते हैं जिनकी आप परवाह करते हैं। जब आप ऑटोमैप के साथ एक प्रॉपर्टी विज़िटर का उपयोग करते हैं, तो यह आपके लिए एक दस्तावेज़ मैपिंग जेनरेट करेगा लेकिन आपको लोचदार खोज पर भेजने से पहले इसे संशोधित करने का मौका देगा। हमें बस इतना करना है कि हमारे कस्टम एट्रिब्यूट के साथ चिह्नित गुणों की तलाश करें और उन्हें एक फ़ील्ड जोड़ें।

public class ProductPropertyVisitor : NoopPropertyVisitor 
{ 
    public override void Visit(IStringProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) 
    { 
     base.Visit(type, propertyInfo, attribute); 

     var wsaf = propertyInfo.GetCustomAttribute<WantsStandardAnalysisField>(); 
     if (wsaf != null) 
     { 
      type.Index = FieldIndexOption.NotAnalyzed; 
      type.Fields = new Properties 
      { 
       { 
        "standard", 
        new StringProperty 
        { 
         Index = FieldIndexOption.Analyzed, 
         Analyzer = "standard" 
        } 
       } 
      }; 
     } 
    } 
} 

आप देख सकते हैं, हम काफी कुछ भी हम उत्पन्न संपत्ति के साथ चाहते हैं, मुख्य संपत्ति के लिए विश्लेषण को बंद करने और के साथ एक नया क्षेत्र जोड़ना भी शामिल कर सकते हैं:

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

आप कोई भी तरीका है कि इस तरह के रूप में एक मानचित्रण Automap का उपयोग कर, उत्पन्न करता है के माध्यम से इस चलाने के लिए थे, तो:

new TypeMappingDescriptor<Product>().AutoMap(new ProductPropertyVisitor()) 

आप इच्छित बहु क्षेत्र मानचित्रण मिल जाएगा। अब आप अपने दिल की सामग्री में मैपिंग को कस्टमाइज़ कर सकते हैं। का आनंद लें!

5

Colin's और Selçuk's उत्तरों के अलावा, आप धाराप्रवाह (और ऑब्जेक्ट प्रारंभकर्ता वाक्यविन्यास) मैपिंग एपीआई के माध्यम से मैपिंग को पूरी तरह से नियंत्रित भी कर सकते हैं। यहाँ अपनी आवश्यकताओं

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var connectionSettings = new ConnectionSettings(pool); 

    var client = new ElasticClient(connectionSettings); 

    client.Map<MyType>(m => m 
     .Index("index-name") 
     .AutoMap() 
     .Properties(p => p 
      .String(s => s 
       .Name(n => n.CompanyName) 
       .Fields(f => f 
        .String(ss => ss 
         .Name("raw") 
         .NotAnalyzed() 
        ) 
       ) 
      ) 
      .Date(d => d 
       .Name(n => n.CreatedDate) 
       .Index(NonStringIndexOption.No)   
      ) 
      .String(s => s 
       .Name(n => n.CompanyDescription) 
       .Store(false) 
      ) 
      .Nested<MyChildType>(n => n 
       .Name(nn => nn.Locations.First()) 
       .AutoMap() 
       .Properties(pp => pp 
        /* properties of MyChildType */ 
       ) 
      ) 
     ) 
    ); 
} 

public class MyType 
{ 
    // Index this & allow for retrieval. 
    public int Id { get; set; } 

    // Index this & allow for retrieval. 
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens. 
    public string CompanyName { get; set; } 

    // Don't index this for searching, but do store for display. 
    public DateTime CreatedDate { get; set; } 

    // Index this for searching BUT NOT for retrieval/displaying. 
    public string CompanyDescription { get; set; } 

    // Nest this. 
    public List<MyChildType> Locations { get; set; } 
} 

public class MyChildType 
{ 
    // Index this & allow for retrieval. 
    public string LocationName { get; set; } 

    // etc. other properties. 
} 

के आधार पर एक उदाहरण यह मानचित्रण

{ 
    "properties": { 
    "id": { 
     "type": "integer" 
    }, 
    "companyName": { 
     "type": "string", 
     "fields": { 
     "raw": { 
      "type": "string", 
      "index": "not_analyzed" 
     } 
     } 
    }, 
    "createdDate": { 
     "type": "date", 
     "index": "no" 
    }, 
    "companyDescription": { 
     "type": "string", 
     "store": false 
    }, 
    "locations": { 
     "type": "nested", 
     "properties": { 
     "locationName": { 
      "type": "string" 
     } 
     } 
    } 
    } 
} 

कॉलिंग .AutoMap() कारणों घोंसला संपत्ति प्रकार के आधार पर मानचित्रण अनुमान लगाने के लिए पैदा करता है और उन्हें करने के लिए लागू कोई गुण है। फिर .Properties() किसी भी अनुमानित मैपिंग को ओवरराइड करता है।उदाहरण के लिए

  • CompanyName क्षेत्र companyName के साथ एक multi_field के रूप में मैप किया गया है मानक विश्लेषक और companyName.raw नहीं विश्लेषण किया का उपयोग कर विश्लेषण किया। आप का उपयोग .Field(f => f.CompanyName.Suffix("raw"))
  • Locations मैप किया गया है आपके प्रश्नों में बाद संदर्भित कर सकते हैं के रूप में एक nested प्रकार (डिफ़ॉल्ट रूप से automapping एक object प्रकार मानचित्रण के रूप में इस का अनुमान लगा होगा)। इसके बाद आप Nested<MyChildType>() कॉल के अंदर .Properties() का उपयोग करके MyChildType के लिए किसी विशेष मैपिंग को परिभाषित कर सकते हैं।
+0

वास्तव में अच्छा जवाब। लगता है कि ज्यादातर मेरे लिए काम करते हैं, हालांकि, मुझे नेस्ट 2.4.2 में 'सिक्सिक्स ("कच्चा")' का उपयोग करने में कोई समस्या थी (यह अभी काम नहीं करता है)। मैंने अभी अंत में '+" .raw "' का उपयोग किया था। – Harvey