2017-11-01 25 views
1

이름에 '.'이 포함되어 있기 때문에 이름을 바꿀 필요가있는 elasticsearch (5.5.1)에 필드가 있습니다. 다양한 문제를 야기하고있다. 이름을 바꿀 필드는 다른 필드 안에 중첩되어 있습니다.elasticsearch rename processor 및 ingest pipeline으로 점을 포함하는 중첩 된 필드의 이름을 바꾸는 방법

여기에 설명 된대로 내가 다시 색인화 작업을 수행하기 위해 인제 스트 파이프 라인에서 이름 바꾸기 프로세서를 사용하는 것을 시도하고있다

: https://stackoverflow.com/a/43142634/5114 여기

내 파이프 라인 시뮬레이션 요청 (테스트 할 키바의 개발 도구 유틸리티로 그대로이 복사 할 수있다 그것은) : 내가 생각

{ 
    "docs": [ 
    { 
     "error": { 
     "root_cause": [ 
      { 
      "type": "exception", 
      "reason": "java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: field [message.message.group1] doesn't exist", 
      "header": { 
       "processor_type": "rename" 
      } 
      } 
     ], 
     "type": "exception", 
     "reason": "java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: field [message.message.group1] doesn't exist", 
     "caused_by": { 
      "type": "illegal_argument_exception", 
      "reason": "java.lang.IllegalArgumentException: field [message.message.group1] doesn't exist", 
      "caused_by": { 
      "type": "illegal_argument_exception", 
      "reason": "field [message.message.group1] doesn't exist" 
      } 
     }, 
     "header": { 
      "processor_type": "rename" 
     } 
     } 
    } 
    ] 
} 

:

POST _ingest/pipeline/_simulate 
{ 
    "pipeline" : { 
     "description": "rename nested fields to remove dot", 
      "processors": [ 
      { 
       "rename" : { 
        "field" : "message.message.group1", 
        "target_field" : "message_group1" 
       } 
      }, 
      { 
       "rename" : { 
        "field" : "message.message.group2", 
        "target_field" : "message.message_group2" 
       } 
      } 
      ] 
    }, 
    "docs":[ 
     { 
      "_type": "status", 
      "_id": "1509533940000-m1-bfd7183bf036bd346a0bcf2540c05a70fbc4d69e", 
      "_version": 5, 
      "_score": null, 
      "_source": { 
       "message": { 
        "_job-id": "AV8wHJEaa4J0sFOfcZI5", 
        "message.group1": 0, 
        "message.group2": "foo" 
       }, 
       "timestamp": 1509533940000 
      } 
     } 
    ] 
} 

문제는 내 파이프 라인을 사용하려고 할 때 오류가 발생하는 것입니다 문제는 "message.group1"필드가 다른 필드 ("message") 안에 있음으로 인해 발생합니다. 프로세서의 컨텍스트에서 원하는 필드를 참조하는 방법을 잘 모르겠습니다. 중첩 된 필드, 점을 포함하는 필드 및 점을 포함하는 중첩 된 필드 사이의 모호성이있을 수 있습니다.

이 필드를 참조하는 올바른 방법을 찾고 있습니다. 또는 Elasticsearch에서 원하는 것을 수행 할 수없는 경우이를 확인할 수 없습니다. Elasticsearch가이 작업을 수행 할 수 있다면 매우 빠를 것입니다. 그렇지 않으면 문서를 가져 와서 변환하고 새 색인에 다시 저장하는 외부 스크립트를 작성해야합니다.

+0

다음과 비슷한 비슷한 이야기가 있습니다. https://stackoverflow.com/questions/36774110/replacing-a-dot-in-an-field-name – Mnebuerquo

답변

0

감사합니다. Elasticsearch 코드를 조사해 보니 왜 이것이 작동하지 않는지 알 것 같습니다.

먼저 우리는 Elasticsearch 이름 바꾸기 프로세서보고 : https://github.com/elastic/elasticsearch/blob/9eff18374d68355f6acb58940a796268c9b6f2de/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RenameProcessor.java#L76-L84

Object value = document.getFieldValue(field, Object.class); 
document.removeField(field); 
try { 
    document.setFieldValue(targetField, value); 
} catch (Exception e) { 
    // setting the value back to the original field shouldn't as we just fetched it from that field: 
    document.setFieldValue(field, value); 
    throw e; 
} 

이것이 필드가 다음, 그 값을 받고 현장을 제거하고 같은과 함께 새로운 필드를 추가, 이름을 찾고있다하고있다 가치가 있지만 새로운 이름으로.

이제 우리는 document.getFieldValue에서 일어나는 것을 보면 : https://github.com/elastic/elasticsearch/blob/9eff18374d68355f6acb58940a796268c9b6f2de/core/src/main/java/org/elasticsearch/ingest/IngestDocument.java#L101-L108

public <T> T getFieldValue(String path, Class<T> clazz) { 
    FieldPath fieldPath = new FieldPath(path); 
    Object context = fieldPath.initialContext; 
    for (String pathElement : fieldPath.pathElements) { 
     context = resolve(pathElement, path, context); 
    } 
    return cast(path, context, clazz); 
} 

사항은이 문서의 필드의 경로를 나타 내기 위해 FieldPath에는 개체를 사용합니다.

이제 FieldPath에는이 경로를 나타내는 방법에 대해 살펴 : "." https://github.com/elastic/elasticsearch/blob/9eff18374d68355f6acb58940a796268c9b6f2de/core/src/main/java/org/elasticsearch/ingest/IngestDocument.java#L688

this.pathElements = newPath.split("\\."); 

이 어떤에 경로를 분할됩니다 왜냐하면 그것은 필드 이름의 경로 요소 사이의 구분 기호이기 때문입니다.

원본 문서의 필드가 "message.group1"이므로 문제를 참조 할 수 있어야합니다. 경로를 "." "."을 포함하는 필드 이름을 고려하지 않습니다. 이름으로. 우리는 자바 스크립트와 같은 구문이 더 필요합니다. 여기서 대괄호와 따옴표를 사용하여 점의 의미를 다르게 지정할 수 있습니다.

원본 문서가 모두 변환되어 "." 필드 이름에 저장하기 전에 해당 필드를 객체로 변환하면이 경로 체계가 작동합니다. 그러나 필드 이름에 "."이 포함 된 소스 문서의 경우 우리는 특정 상황에서 그들을 참조 할 수 없습니다.

내 색인을 다시 작성하고 색인을 다시 작성하기 위해 문서 일괄 처리를 가져온 파이썬 스크립트를 작성하여 새로운 색인으로 대량 삽입했습니다. 이것은 기본적으로 Elasticsearch reindex api가하는 일이지만, 파이썬으로 대신했습니다.