2016-12-01 7 views
1

アプリケーションをElasticSearch Nest 1.7から2.4にアップグレードしようとしていますが、属性ベースのマッピングはのようになりますが、の場合は動作しますが、(完全に)動作しません。ElasticSearch 2.xの属性マッピングで「NotAnalyzed」が無視される

[DataContract] 
[ElasticsearchType(IdProperty = "Id")] 
public class Series 
{ 
    [DataMember] 
    [String(Index = FieldIndexOption.Analyzed, Analyzer = "custom_en")] 
    public string Description { get; set; } 

    [DataMember] 
    [String(Index = FieldIndexOption.NotAnalyzed)] 
    public HashSet<Role> ReleasableTo { get; set; } 
} 

Nest 1.xの同等の宣言が機能していて、フィールドに対する私の用語クエリが、私が期待していた結果を返しました。結果が届かなかった場合は、マッピングを確認しましたが、驚いたことにIndex = FieldIndexOption.NotAnalyzedは尊敬されませんでした。だから、

"properties" : { 
    "description" : { 
     "type": "string" 
    } 
    "releasableTo" : { 
     "type": "string" 
    } 
} 

私はカスタム・アナライザ・セットが適切にマークされていた、また私が分析されていない必要なフィールドが正しくマークされていた持っていたどちらのフィールド:私の生成されたマッピングは、このようなものでした。

これは、私はすべての初期化を呼び出すために使用するコードです:

  var indexDescriptor = new CreateIndexDescriptor(DefaultIndex) 
       .Mappings(ms => ms 
        .Map<Series>(m => m.AutoMap()) 
       ) 
      ); 

      indexDescriptor.Settings(s => s 
       .NumberOfShards(3) 
       .NumberOfReplicas(2) 
       .Analysis(a => a 
        .CharFilters(c => c.Mapping("&_to_and", mf => mf.Mappings("&=> and "))) 
        .TokenFilters(t => t.Stop("en_stopwords", tf=>tf.StopWords(new StopWords(stopwords)).IgnoreCase())) 
        .Analyzers(z => z 
         .Custom("custom_en", ca => ca 
          .CharFilters("html_strip", "&_to_and") 
          .Tokenizer("standard") 
          .Filters("lowercase", "en_stopwords") 
         ) 
        ) 
       ) 
      ); 

      client.CreateIndex(indexDescriptor); 

注:clientがelasticsearchクライアントです。

私はDataContract属性が厳密にElasticSearchには適用されないことを知っていますが、これらのオブジェクトをディスクにシリアル化して処理する必要もあります。 Nest 1.xでは競合はなく、問題はありませんでした。

私はアナライザー作成について心配していません。私はマッピングが型よりも具体的なものを尊重しないことに懸念しています。

マッピングの宣言時にNest 2.xが属性の追加情報を尊重するように手動でマッピングする必要はありません。


だから、マッピングの問題が同時にマッピングされた他のタイプとしなければならなかったことが判明。私が捕まえなかったインデックスからの無効な回答がありました。作業が非常にイライラしましたが、マッピングが正しく機能しています。

+0

注:@RussCamが答えで指摘したタイプミスを修正しました。 –

答えて

1

タイプミスかどうかわかりませんが、属性のタイプがSeriesですが、タイプはServiceです。

あなたが見ているものをNEST 2.5.0で再現することはできません。ここではこれはInMemoryConnectionを使用する完全な例

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "default-index"; 
    var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection()) 
      .DefaultIndex(defaultIndex) 
      .PrettyJson() 
      .DisableDirectStreaming() 
      .OnRequestCompleted(response => 
       { 
        // log out the request 
        if (response.RequestBodyInBytes != null) 
        { 
         Console.WriteLine(
          $"{response.HttpMethod} {response.Uri} \n" + 
          $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}"); 
        } 
        else 
        { 
         Console.WriteLine($"{response.HttpMethod} {response.Uri}"); 
        } 

        Console.WriteLine(); 

        // log out the response 
        if (response.ResponseBodyInBytes != null) 
        { 
         Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
           $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" + 
           $"{new string('-', 30)}\n"); 
        } 
        else 
        { 
         Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
           $"{new string('-', 30)}\n"); 
        } 
       }); 

    var client = new ElasticClient(connectionSettings); 

    var stopwords = "stopwords"; 

    var indexDescriptor = new CreateIndexDescriptor(defaultIndex) 
     .Mappings(ms => ms 
      .Map<Series>(m => m.AutoMap()) 
     ); 

    indexDescriptor.Settings(s => s 
     .NumberOfShards(3) 
     .NumberOfReplicas(2) 
     .Analysis(a => a 
      .CharFilters(c => c.Mapping("&_to_and", mf => mf.Mappings("&=> and "))) 
      .TokenFilters(t => t.Stop("en_stopwords", tf => tf.StopWords(new StopWords(stopwords)).IgnoreCase())) 
      .Analyzers(z => z 
       .Custom("custom_en", ca => ca 
        .CharFilters("html_strip", "&_to_and") 
        .Tokenizer("standard") 
        .Filters("lowercase", "en_stopwords") 
       ) 
      ) 
     ) 
    ); 

    client.CreateIndex(indexDescriptor); 

} 

[DataContract] 
[ElasticsearchType(IdProperty = "Id")] 
public class Series 
{ 
    [DataMember] 
    [String(Index = FieldIndexOption.Analyzed, Analyzer = "custom_en")] 
    public string Description { get; set; } 

    [DataMember] 
    [String(Index = FieldIndexOption.NotAnalyzed)] 
    public HashSet<Role> ReleasableTo { get; set; } 
} 

ですので、何の要求は(これは実際にリクエストを送信するために除去することができます)Elasticsearchに行われません。作成インデックス要求は、それぞれの特性マッピングを有する

{ 
    "settings": { 
    "index.number_of_replicas": 2, 
    "index.number_of_shards": 3, 
    "analysis": { 
     "analyzer": { 
     "custom_en": { 
      "type": "custom", 
      "char_filter": [ 
      "html_strip", 
      "&_to_and" 
      ], 
      "filter": [ 
      "lowercase", 
      "en_stopwords" 
      ], 
      "tokenizer": "standard" 
     } 
     }, 
     "char_filter": { 
     "&_to_and": { 
      "type": "mapping", 
      "mappings": [ 
      "&=> and " 
      ] 
     } 
     }, 
     "filter": { 
     "en_stopwords": { 
      "type": "stop", 
      "stopwords": "stopwords", 
      "ignore_case": true 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "series": { 
     "properties": { 
     "description": { 
      "type": "string", 
      "index": "analyzed", 
      "analyzer": "custom_en" 
     }, 
     "releasableTo": { 
      "type": "string", 
      "index": "not_analyzed" 
     } 
     } 
    } 
    } 
} 

のようになります。インデックスがすでに存在する場合、マッピングの変更は適用されないため、この場合はインデックスを削除して作成する必要があることに注意してください。

+0

私は自分の問題に関連していると思ったものをすべて削除したので、それはタイプミスでした。私はautomapするために必要ないくつかのタイプがあり、 'Service'はもう一つです。私はリストを二重にチェックして、私が同じことを二度マッピングしていないか、またはコードで 'Series'を完全に見つけられていないことを確認します。 –

+0

補足として、検索結果の有用性を損なうものを除外するために、埋め込まれたファイル(手元の問題では重要ではない)から、改行で区切られたストップワードのリストを読みました。私はあなたがこれを知っていると確信していますが、私は後であなたのコードを読んで来る誰かのために声明を出しています。 –

+0

OK、インデックスを作成すると、別のタイプの例外のためにマッピングが破棄されたように見えます。 –

関連する問題