2016-12-14 2 views
0

Ich versuche, eine dynamische Vorlage in ES zu verwenden, so dass alle Zeichenfolgenfelder Multifelder sind. Ich möchte auch bestimmte Zuordnungen auf bestimmte Felder anwenden.ElasticSearch Nest: AutoMap mit DynamicTemplates

Nehmen Sie das folgende Beispiel-Klasse:

[ElasticsearchType(Name = "sample1")] 
public class Sample1 
{ 
    public string ID { get; set; } 

    [String(Index = FieldIndexOption.No)] 
    public string DoNotIndex { get; set; } 

    public string MultiField1 { get; set; } 

    public string MultiField2 { get; set; } 
} 

Ich möchte dann die dynamische Vorlage erstellen und die Zuordnung zu DoNotIndex mit dem folgenden Befehl anwenden:

_client.Map<Sample1>(m => m 
    .AutoMap() 
    .DynamicTemplates(dt=> dt 
     .DynamicTemplate("all_strings_multifields", t => t 
     .MatchMappingType("string") 
     .Mapping(tm => tm 
      .String(mf => mf 
       .Index(FieldIndexOption.Analyzed) 
       .Fields(mff => mff 
        .String(s => s 
         .Name("raw") 
         .Index(FieldIndexOption.NotAnalyzed) 
        ) 
       ) 
      ) 
     ) 
    ) 
    ) 
) 
.VerifySuccessfulResponse(); 

Das Ergebnis ist:

{ 
    "test1": { 
    "mappings": { 
     "sample1": { 
     "dynamic_templates": [ 
      { 
      "all_strings_multifields": { 
       "match_mapping_type": "string", 
       "mapping": { 
       "fields": { 
        "raw": { 
        "type": "string", 
        "index": "not_analyzed" 
        } 
       }, 
       "index": "analyzed", 
       "type": "string" 
       } 
      } 
      } 
     ], 
     "properties": { 
      "doNotIndex": { 
      "type": "keyword", 
      "index": false 
      }, 
      "iD": { 
      "type": "text" 
      }, 
      "multiField1": { 
      "type": "text" 
      }, 
      "multiField2": { 
      "type": "text" 
      } 
     } 
     } 
    } 
    } 
} 

Ergebnisse

Sie sehen, dass die DoNotIndex Eigenschaft ist zwar richtig, aber die multifield1 und multifield2 sind nicht korrekt (sie sind nicht Multifelder).

Umgehung

Ich weiß, dass ich „reparieren“ kann dies durch NICHT die AutoMap() tun und stattdessen jedes der spezielle Indizes spezifiziert, aber es gibt eine Menge von Feldern und das ist nicht so sauber eine Lösung.

Kann ich AutoMap mit DynamicTemplates erstellen?

Antwort

2

Dynamic templates nur auf Felder anwenden, die dynamisch zu einem Mapping hinzugefügt werden, sodass Eigenschaften, die explizit mit .AutoMap() zugeordnet wurden, nicht vom dynamischen Mapping betroffen sind.

Es gibt jedoch eine Möglichkeit, Konventionen für explizite Zuordnungen mit NEST unter Verwendung des Besuchermusters anzuwenden. Es sieht aus wie du bist Elasticsearch 5.0, so you should use the text and keyword mappings.

Zuerst definieren einen Besucher

[ElasticsearchType(Name = "sample1")] 
public class Sample1 
{ 
    public string ID { get; set; } 

    [Keyword(Index = false)] 
    public string DoNotIndex { get; set; } 

    public string MultiField1 { get; set; } 

    public string MultiField2 { get; set; } 
} 

public class AllStringsMultiFieldsVisitor : NoopPropertyVisitor 
{ 
    public override void Visit(ITextProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) 
    { 
     // if a custom attribute has been applied, let it take precedence 
     if (propertyInfo.GetCustomAttribute<ElasticsearchPropertyAttributeBase>() == null) 
     { 
      type.Fields = new Properties 
      { 
       { 
        "raw", new KeywordProperty() 
       } 
      }; 
     } 

     base.Visit(type, propertyInfo, attribute); 
    } 
} 

dann eine Instanz des Besuchers passieren zu .AutoMap()

client.Map<Sample1>(m => m 
    .AutoMap(new AllStringsMultiFieldsVisitor()) 
    .DynamicTemplates(dt => dt 
     .DynamicTemplate("all_strings_multifields", t => t 
      .MatchMappingType("text") 
      .Mapping(tm => tm 
       .Text(mf => mf 
        .Index(true) 
        .Fields(mff => mff 
         .Keyword(s => s 
          .Name("raw") 
         ) 
        ) 
       ) 
      ) 
     ) 
    ) 
); 

mit produziert

{ 
    "dynamic_templates": [ 
    { 
     "all_strings_multifields": { 
     "match_mapping_type": "text", 
     "mapping": { 
      "type": "text", 
      "fields": { 
      "raw": { 
       "type": "keyword" 
      } 
      }, 
      "index": true 
     } 
     } 
    } 
    ], 
    "properties": { 
    "iD": { 
     "fields": { 
     "raw": { 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    }, 
    "doNotIndex": { 
     "type": "keyword", 
     "index": false 
    }, 
    "multiField1": { 
     "fields": { 
     "raw": { 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    }, 
    "multiField2": { 
     "fields": { 
     "raw": { 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    } 
    } 
} 

Ich sollte jedoch darauf hinweisen, dass die default automapping for a C# string property in NEST 5.0 ist, um es als text Feld mit einem keyword Unterfeld mit ignore_above:256 abzubilden. NEST 5.0 was released to nuget earlier this week

client.Map<Sample1>(m => m 
    .AutoMap() 
    .DynamicTemplates(dt => dt 
     .DynamicTemplate("all_strings_multifields", t => t 
      .MatchMappingType("text") 
      .Mapping(tm => tm 
       .Text(mf => mf 
        .Index(true) 
        .Fields(mff => mff 
         .Keyword(s => s 
          .Name("raw") 
         ) 
        ) 
       ) 
      ) 
     ) 
    ) 
); 

produziert

{ 
    "dynamic_templates": [ 
    { 
     "all_strings_multifields": { 
     "match_mapping_type": "text", 
     "mapping": { 
      "type": "text", 
      "fields": { 
      "raw": { 
       "type": "keyword" 
      } 
      }, 
      "index": true 
     } 
     } 
    } 
    ], 
    "properties": { 
    "iD": { 
     "fields": { 
     "keyword": { 
      "ignore_above": 256, 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    }, 
    "doNotIndex": { 
     "type": "keyword", 
     "index": false 
    }, 
    "multiField1": { 
     "fields": { 
     "keyword": { 
      "ignore_above": 256, 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    }, 
    "multiField2": { 
     "fields": { 
     "keyword": { 
      "ignore_above": 256, 
      "type": "keyword" 
     } 
     }, 
     "type": "text" 
    } 
    } 
} 
+1

YES! Danke Russ, der Beispielcode mit dem Besuchermuster hat super funktioniert. Ich habe es für ES 2.x anstelle von 5.x optimiert und alles sieht gut aus. Du schaukelst! – jhilden

Verwandte Themen