2016-12-14 7 views
0

私はすべての文字列フィールドがマルチフィールドであるようにESで動的テンプレートを使用しようとしています。特定のフィールドにいくつかの特定のマッピングを適用したいと思っています。ElasticSearchネスト:DynamicTemplatesを使用したAutoMap

次の例のクラスを取る:

[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; } 
} 

私は、動的テンプレートを作成し、次のコマンドを使用してDoNotIndexへのマッピングを適用する:

_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(); 

結果は次のとおりです。

{ 
    "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" 
      } 
     } 
     } 
    } 
    } 
} 

結果

DoNotIndexプロパティは実際に正しいと表示されますが、multifield1multifield2は正しくありません(マルチフィールドではありません)。

回避策

は私がAutoMap()をやって、代わりに特殊なインデックスのそれぞれを指定するが、フィールドがたくさんあるませことによって、これを「修正」することができます知っていて、それが解決策のようにきれいではありません。

DynamicTemplatesでAutoMapを実行できますか?

答えて

2

Dynamic templatesは、マッピングに動的に追加されるフィールドにのみ適用されるため、.AutoMap()で明示的にマップされたプロパティは動的マッピングの影響を受けません。

しかし、ビジターパターンを使用してNESTを使用した明示的なマッピングに慣習を適用する方法があります。それはあなたが次に.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") 
         ) 
        ) 
       ) 
      ) 
     ) 
    ) 
); 

への訪問者のインスタンスを渡す訪問者

[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); 
    } 
} 

を定義Elasticsearch 5.0、 so you should use the text and keyword mappings.

ファーストを使用しているように見えます

{ 
    "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" 
    } 
    } 
} 
を生成します

しかし、default automapping for a C# string property in NEST 5.0textフィールドとkeywordサブフィールドがignore_above:256でマッピングされることを指摘します。 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") 
         ) 
        ) 
       ) 
      ) 
     ) 
    ) 
); 

YES

{ 
    "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

を作り出します!ラス、ありがとう、訪問者のパターンとのサンプルコードは素晴らしい仕事をした。私は5.xの代わりにES 2.xのためにそれを微調整し、すべてが良く見えます。あなたはロック! – jhilden

関連する問題