2016-12-01 5 views
1

ElasticSearch Nest 1.7에서 2.4로 응용 프로그램을 업그레이드하려고하는데 특성 기반 매핑이 일 때 일 필요가 있지만 (완전히) 그렇지 않습니다. 다음과 같은 모델 클래스가 있습니다 :ElasticSearch 2.x 특성 매핑에서 "NotAnalyzed"을 무시합니다.

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

오타였습니다. 제가 문제를 해결할 수 있다고 생각했던 것을 제외하고 모두 삭제했습니다. 자동 매핑을 수행하는 데 필요한 유형이 많이 있으며 '서비스'가 또 다른 유형입니다. 나는 같은 것을 두 번 매핑하지 않거나 내 코드에서'Series'를 완전히 빠뜨리지 않도록 목록을 두 번 확인합니다 .... –

+0

부수적으로, 필자는 검색 결과의 유용성을 떨어 뜨리는 내용을 제거하기 위해 포함 된 파일 (근본적인 문제는 중요하지 않음)에서 새 단어로 구분 된 중지 단어 목록을 읽었습니다. 나는 당신이 이것을 알고있을 것이라고 확신하지만, 나는 나중에 나오고 코드를 읽는 다른 누군가를 위해 성명서를 작성하고있다. –

+0

좋아, 그것은 인덱스를 만들 때 다른 유형의 예외로 인해 매핑이 파괴 된 것 같습니다. –