elasticsearch의 Mapping conflict 해결

Elasticsearch에서 필드 유형에서 충돌이 발생했을 때 해소하기 전에 한 단계를 작성합니다.
이번에는 충돌을 해소하는데 Elasticsearch의 퍼스 기능을 이용하기 때문에, 퍼스 할 수 없는 데이터는 잘라냅니다. 예를 들어, "100"-> 100은 구문 분석할 수 있지만 "100MB"-> 100은 구문 분석할 수 없습니다. 이 방법으로 통용하는 경우는 뭔가 참고가 될지도 모릅니다.

환경


  • Windows 10
  • Elasticsearch 7.3.0
  • Kibana 7.3.0

  • 이전 준비



    이번에는 설명을 위해 의도적으로 충돌하는 더미 데이터를 만듭니다. 다음 쿼리를 Kibana의 dev tools에서 실행합니다.
    POST _bulk
    { "index" : { "_index" : "test1", "_id" : "1" } }
    { "name" : "aaa", "num": 100 }
    { "create" : { "_index" : "test1", "_id" : "2" } }
    { "name" : "bbb", "num": 200 }
    { "index" : { "_index" : "test2", "_id" : "1" } }
    { "name" : "aaa", "num": "100" }
    { "create" : { "_index" : "test2", "_id" : "2" } }
    { "name" : "bbb", "num": "200B" }
    

    이 상태에서 Management/Index Patterns 에서 「 test* 」로 Create index pattern 합니다.test* 를 열면 아래 그림과 같이 Mapping이 충돌하고 있다고 경고가 나온다고 생각합니다. num 의 Type이 conflict가 되어 있는 것을 확인할 수 있으면 성공 (?)입니다.


    이상으로 전 준비로서는 종료입니다. 다음으로 충돌을 해소하는 순서입니다.

    절차



    이번은 numlong 로 하는 방향으로 컨플릭트를 해소합니다. 그 때문에, test2 의 Mapping 를 수정할 필요가 있습니다. 그러나 Elasticsearch에는 Mapping을 수정하는 기능은 존재하지 않는 것처럼 index를 다시 만들 수밖에 없다고 합니다. 따라서 test2를 다른 index에 복사하고 놓치고 올바른 Type으로 다시 매핑 한 test2로 다시 복사하는 방법을 취합니다.

    1. test2 임시 저장용 Mapping 만들기



    이 때 충돌하고 있는 필드의 Type을 명시적으로 지정합니다. 이번에는 num의 Type을 long으로 지정합니다.
    PUT tmp-test2
    {
      "mappings": {
        "properties": {
          "num": {
            "type": "long"
          }
        }
      }
    }
    

    2. 임시 저장처에 내용을 복사



    _reindex는 한 index의 내용을 다른 index로 복사하는 Elasticsearch의 API입니다. failures가 나온다고 생각합니다만, 이것은 num 하지만 200B 의 document가 원인으로 나와 있는 것입니다. 처음에 설명한 대로 이번 방법에서는 이렇게 Elasticsearch가 퍼스 할 수 없는 값은 잘라냅니다.
    POST _reindex
    {
      "source": {
        "index": "test2"
      },
      "dest": {
        "index": "tmp-test2"
      }
    }
    
    // RETURN
    // {
    //   "took": 41,
    //   "timed_out": false,
    //   "total": 2,
    //   "updated": 0,
    //   "created": 1,
    //   "deleted": 0,
    //   "batches": 1,
    //   "version_conflicts": 0,
    //   "noops": 0,
    //   "retries": {
    //     "bulk": 0,
    //     "search": 0
    //   },
    //   "throttled_millis": 0,
    //   "requests_per_second": -1,
    //   "throttled_until_millis": 0,
    //   "failures": [
    //     {
    //       "index": "tmp-test2",
    //       "type": "_doc",
    //       "id": "2",
    //       "cause": {
    //         "type": "mapper_parsing_exception",
    //         "reason": "failed to parse field [num] of type [long] in document with id '2'. Preview of field's value: '200B'",
    //         "caused_by": {
    //           "type": "illegal_argument_exception",
    //           "reason": "For input string: \"200B\""
    //         }
    //       },
    //       "status": 400
    //     }
    //   ]
    // }
    
    

    3. test2의 index 삭제



    삭제하는 것이 무서운 경우는 snapshot 등을 활용하여 백업을 취하십시오. 이번에는 snapshot에 대해서는 쓰지 않으므로 다음 기사 등을 참고하십시오.
    htps : // 이 m / 오카루 / ms / 82b1 예 5d249c3dc01452
    DELETE test2
    

    4. test2의 Mapping 만들기


    PUT test2
    {
      "mappings": {
        "properties": {
          "num": {
            "type": "long"
          }
        }
      }
    }
    

    5. 임시 저장처에서 test2로 내용을 복사


    POST _reindex
    {
      "source": {
        "index": "tmp-test2"
      },
      "dest": {
        "index": "test2"
      }
    }
    

    6. 임시 저장 위치 삭제


    DELETE tmp-test2
    

    7. test* 에서 Refresh field list



    Management/Index Pattern에서 test* 를 클릭하고 오른쪽 상단의 새로고침 버튼을 눌러 Refresh field list 합니다.

    8. 충돌 해결 🙌





    사이고에게



    Discover에서 test*를 살펴 보겠습니다. 데이터가 3개밖에 없습니다. test2 의 _id2 문서는 구문 분석 할 수 없었기 때문에 _reindex로 복사되지 않았기 때문입니다. 조심하세요.



    실수 · 더 좋은 방법 등 있으면 지적하실 수 있으면 기쁩니다.
    이 기사가 누군가의 도움이되면 다행입니다.
    질문은 @mn_chorome까지.

    참고


  • h tps : // / s s. 에스 c. 코/t/호 w-와-후-x-마핀 g-안 fぃct/55072? 그래 r세_와 피 c_이 d=92945
  • htps : // 메이 m. 코 m / @ 에야 l 다하리 / 린데 x - 에 s 치 c 세 아 rch - 쿠멘 ts - 이 s 에 에 r
  • 좋은 웹페이지 즐겨찾기