ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서울시 지하철 대시보드1 - 전처리
    엔지니어링/ELK 2021. 7. 31. 15:26
    728x90
    • reference

    https://github.com/eskrug/elastic-demos 

     

    GitHub - eskrug/elastic-demos: Elastic 한국 커뮤니티에서 만든 데모 모음입니다

    Elastic 한국 커뮤니티에서 만든 데모 모음입니다. Contribute to eskrug/elastic-demos development by creating an account on GitHub.

    github.com

    https://www.youtube.com/watch?v=ypsEZXVYLo4&list=PLhFRZgJc2afqxJx0RBKkYUxSUDJNusXPl 


    1. 준비

    프로그램 준비

    • 디렉토리 생성

    > git 파일 복제 후, seoul-metro-logs 디렉토리에 진입

    $ cd
    $ git clone https://github.com/eskrug/elastic-demos.git
    $ cd elastic-demos/seoul-metro-logs
    • data 디렉토리 생성
    $ mkdir data

     

    공공데이터 수집

    • 데이터 다운로드 (wget 안됨, 로컬에 직접 받아준다)

    > 데이터가 많이 바뀌어서 반드시 첨부한 데이터로 사용바랍니다. 

    > 서울시 열린데이터 광장

    1. 서울시 역코드로 지하철역 위치 조회

    https://gaussian37.github.io/python-etc-수도권-지하철/ 

     

    수도권 지하철 좌표

    gaussian37's blog

    gaussian37.github.io

    station_info.json
    0.11MB

    2. 서울교통공사 지하철 역명 다국어 표기 정보

    http://data.seoul.go.kr/dataList/OA-2751/F/1/datasetView.do 

     

    서울교통공사 지하철 역명 다국어 표기 정보

    1~8호선 지하철 역명에 대한 한글, 한자, 영자, 중국어, 일어 표기 정보 서비스 입니다.

    data.seoul.go.kr

    station_lang.json
    0.05MB

    3. 서울교통공사 연도별 일별 시간대별 역별 승하차 인원

    http://data.seoul.go.kr/dataList/OA-12921/F/1/datasetView.do 

     

    서울교통공사 연도별 일별 시간대별 역별 승하차 인원

    서울교통공사 연도별 일별 시간대별 역별 승하차인원 (2008년~2019년)

    data.seoul.go.kr

    > 2018년도 데이터 다운로드

    > 1행 삭제, '구분' 열 삭제

    > 인코등 EUC-KR에서 UTF-8로 변경

     

    • 다운로드 받은 파일을 source 디렉토리에 저장

    2. 전처리

    파일 변환 프로그램 실행

    • npm 설치
    $ cd /elastic-demos/seoul-metro-logs
    
    $ apt install npm
    
    $ npm install 
    elastic-demo@1.0.0 /root/elastic-demos/seoul-metro-logs
    └── csv-parse@1.3.3
    #만약 npm install이 잘 안되면 다음 명령어를 통해 패키지 모두 삭제 후 다시 설치한다.
    $ apt autoremove npm
    • 변환 프로그램 수정 (데이터도 다르고ㅡ 코드가 업데이트돼서 별도로 수정 필요)

    station_meta.js

    var fs = require('fs');
    // var parse = require('csv-parse');
    
    var sInfo = fs.readFileSync('source/station_info.json', 'utf8');
    var sLang = fs.readFileSync('source/station_lang.json', 'utf8');
    var sLocation = JSON.parse(sInfo).DATA;
    var sNames = JSON.parse(sLang).DATA;
    // console.log(sLocation.length);
    // console.log(sNames);
    
    // 2020-01 지하철역 주소 및 전화번호 정보 추가
    //var fsAddr1to4 = fs.readFileSync('source/station_addr_1to4.json', 'utf8');
    //var sAddr1to4 = JSON.parse(fsAddr1to4).DATA;
    //var fsAddr5to8 = fs.readFileSync('source/station_addr_5to8.json', 'utf8');
    //var sAddr5to8 = JSON.parse(fsAddr5to8).DATA;
    
    //위치정보 정리
    //var location_meta = new Object();
    var location_meta = new Array();
    for(var i = 0; i < sLocation.length; i++){
      if(sLocation[i].xpoint !== "" && 
          (sLocation[i].line_num === "1" || sLocation[i].line_num === "2" || sLocation[i].line_num === "3" || sLocation[i].line_num === "4" || 
          sLocation[i].line_num === "5" || sLocation[i].line_num === "6" || sLocation[i].line_num === "7" || sLocation[i].line_num === "8" ||
           sLocation[i].line_num === "I" || sLocation[i].line_num === "B")
        ){
        //"서울" 은 "서울역" 으로 이름 변경.
        if(sLocation[i].station_nm === "서울"){ sLocation[i].station_nm = "서울역" }
        //
        
        location_meta.push({
          //"line_num" : sLocation[i].line_num,
          //"station_code" : parseInt(sLocation[i].station_cd),
          "station_nm" : sLocation[i].station_nm,
          //"line_num" : Number(sLocation[i].line_num),
          "geo_x" : Number(sLocation[i].xpoint),
          "geo_y" : Number(sLocation[i].ypoint)
        });
        // console.log("%j",location_meta[location_meta.length-1]);
      }
    }
    //console.log(location_meta); //드디어 잘 쌓임
    
    //다국어 역 정보 정리
    var language_meta = new Object();
    for(var i = 0; i < sNames.length; i++){
      if(sNames[i].stn_nm !== ""){
        var stn_name = sNames[i].stn_nm;
        
        var stn_nm_short = "";
    
        // 광나루\n(장신대) 같은 줄바꿈 이름 앞 이름만 따옴.
        if(sNames[i].stn_nm.indexOf("\n") > 0){
          stn_nm_short = sNames[i].stn_nm.split("\n")[0];
        } else {
          stn_nm_short = sNames[i].stn_nm;
        }
    
        // 총신대입구(이수) 같은 "(" 앞 이름만 따옴
        if(sNames[i].stn_nm.indexOf("(") > 0){
          stn_nm_short = sNames[i].stn_nm.split("(")[0];
        } else {
          stn_nm_short = sNames[i].stn_nm;
        }
    
        language_meta[stn_nm_short] = {
          "stn_nm_kor" : sNames[i].stn_nm,
          "stn_nm_chc" : sNames[i].stn_nm_chc,
          "stn_nm_eng" : sNames[i].stn_nm_eng,
          "stn_nm_chn" : sNames[i].stn_nm_chn,
          "stn_nm_jpn" : sNames[i].stn_nm_jpn
        }
      }
    }
    //console.log(language_meta);
    
    //메타 병합
    var stations_meta = new Object();
    // console.log(location_meta.length); //629
    for(var i=0; i < location_meta.length; i++){
      //console.log(language_meta[location_meta[i].station_nm]);
      //console.log(location_meta[i].station_nm);
    
      if(location_meta[i].station_nm === "총신대입구(이수)") { location_meta[i].station_nm = "이수"; }
      if(language_meta[location_meta[i].station_nm]){
        stations_meta[location_meta[i].station_nm] = {
          //"line_num" : location_meta[i].line_num,
          //"station_code" : location_meta[i].station_code,
          "stn_nm" : location_meta[i].station_nm.replace("\n",""),
          "stn_nm_kor" : language_meta[location_meta[i].station_nm].stn_nm_kor.replace("\n",""),
          "stn_nm_chc" : language_meta[location_meta[i].station_nm].stn_nm_chc.replace("\n",""),
          "stn_nm_eng" : language_meta[location_meta[i].station_nm].stn_nm_eng.replace("\n",""),
          "stn_nm_chn" : language_meta[location_meta[i].station_nm].stn_nm_chn.replace("\n",""),
          "stn_nm_jpn" : language_meta[location_meta[i].station_nm].stn_nm_jpn.replace("\n",""),
          "geo_x" : location_meta[i].geo_x,
          "geo_y" : location_meta[i].geo_y
        }
      } else {
        stations_meta[location_meta[i].station_nm] = {
          //"station_code" : location_meta[i].station_code,
          "stn_nm" : location_meta[i].station_nm.replace("\n",""),
          "geo_x" : location_meta[i].geo_x,
          "geo_y" : location_meta[i].geo_y
        }
      }
    }
    //console.log(stations_meta); //드디어 잘 쌓임
    module.exports = stations_meta;
    
    //for(var i=0; i < sAddr1to4.length; i++){
      // console.log(sAddr1to4[i]);
    //  if(sAddr1to4[i].statn_nm === "신천") { sAddr1to4[i].statn_nm = sAddr1to4[i].statn_nm.replace("신천","잠실새내") }
    //  if(sAddr1to4[i].statn_nm === "총신대입구") { sAddr1to4[i].statn_nm = sAddr1to4[i].statn_nm.replace("총신대입구","이수") }
      
    //  if(stations_meta[sAddr1to4[i].statn_nm]){
    //    stations_meta[sAddr1to4[i].statn_nm].address = sAddr1to4[i].adres;
    //    stations_meta[sAddr1to4[i].statn_nm].road_address = sAddr1to4[i].rdnmadr;
    //    stations_meta[sAddr1to4[i].statn_nm].phone = sAddr1to4[i].telno;
    //  }
      // console.log(sAddr1to4[i]);
    //}
    
    //for(var i=0; i < sAddr5to8.length; i++){
    //  if(sAddr5to8[i] && sAddr5to8[i].stn_nm !== "서울역" ){
    //    if(sAddr5to8[i].stn_nm === "역촌역"){
    //      sAddr5to8[i].stn_nm = "역촌";
    //    } else {
    //      sAddr5to8[i].stn_nm = sAddr5to8[i].stn_nm.split("역")[0];
    //    }
    //  }
    //  if(stations_meta[sAddr5to8[i].stn_nm]){
    //    stations_meta[sAddr5to8[i].stn_nm].address = sAddr5to8[i].stn_addr;
    //    stations_meta[sAddr5to8[i].stn_nm].road_address = sAddr5to8[i].stn_road_addr;
    //    stations_meta[sAddr5to8[i].stn_nm].phone = sAddr5to8[i].stn_phone;
    //  }
      // console.log(sAddr5to8[i]);
    //}

    run.js

    var fs = require('fs');
    var parse = require('csv-parse');
    var s_meta = require('./stations_meta');
    
    //분석할 파일 이름 정확히 기입
    var f1to4 = fs.readFileSync('source/metro_log_2018.csv', 'utf8');
    
    parse(f1to4, {comment:"#"}, function(csv_err, csv_data){
      if (csv_err) {
        return console.log(csv_err);
      }
      
      // csv 파일 형태는 아래와 같이 되어야 함.
      // 0            1      2        3       4     5       6       7       ... 23      24      25
      // 날짜,        호선,   역번호, 역명,   구분, 05~06,  06~07,  07~08,  ... 23~24,  00~01,  합계
      // 2018-01-01,  1호선,  150,    서울역, 승차, 373,    318,    365,    ... 781,    96,     40393
    
      // 2줄씩 루프 돌면서 0~3 열 까지의 데이터가 동일한지 확인
      for(var cd=1; cd< csv_data.length ; cd+=2){
        var dataIn = csv_data[cd];
        var dataOut = csv_data[cd+1];
        if(dataIn[0]===dataOut[0] && dataIn[1]===dataOut[1] 
          && dataIn[2]===dataOut[2] && dataIn[3]===dataOut[3]){
          // 역명
          var station_name = dataIn[3];
          // 날짜
          var ldateTemp = dataIn[0].split('-');
          // 시간 값으로 루프
          for(var h=0; h < 20; h++){
            var ldate = new Date(ldateTemp[0],Number(ldateTemp[1])-1,ldateTemp[2],h);
            // 승차인원
            var people_in = dataIn[5+h];
            people_in = Number(people_in);
    
            // 하차인원
            var people_out = dataOut[5+h];
            people_out = Number(people_out);
            
            var line_num_lang = {
              "1호선" : "Line 1", "2호선" : "Line 2", "3호선" : "Line 3", "4호선" : "Line 4", 
              "5호선" : "Line 5", "6호선" : "Line 6", "7호선" : "Line 7", "8호선" : "Line 8"
            }
    
            // 역명에 () 포함하는 값들 모두 치환
            var stn_nm_full = station_name;
            if(station_name.indexOf("(") > 0){
              station_name = station_name.split("(")[0];
            }
    
            // if(h===0){
            //   console.log("station_name: "+station_name);
            //   console.log("stn_nm_full: "+ stn_nm_full);
            // }
            var s_logs = {};
            var t_st_nm = station_name;
    
    
            if(station_name === "총신대입구") {
              t_st_nm = "이수"; 
              stn_nm_full = "총신대입구(이수)"
            } else {
              if(!s_meta[t_st_nm]){
                // if(h===0){ console.log("s_meta[stn_nm_full]: %j ",s_meta[stn_nm_full]); }
                t_st_nm = stn_nm_full;
              }
            }
            // if(h===0 ){ console.log(t_st_nm); }
    
            if(s_meta[t_st_nm].stn_nm_kor){
              s_logs = {
                "@timestamp" : ldate,
                "code": dataIn[2],
                "line_num" : dataIn[1],
                "line_num_en" : line_num_lang[dataIn[1]],
                "station": {
                  "name" : stn_nm_full,
                  "kr" : s_meta[t_st_nm].stn_nm_kor,
                  "en" : s_meta[t_st_nm].stn_nm_eng,
                  "chc" : s_meta[t_st_nm].stn_nm_chc,
                  "ch" : s_meta[t_st_nm].stn_nm_chn,
                  "jp" : s_meta[t_st_nm].stn_nm_jpn
                },
                "location" : {
                  "lat" : s_meta[t_st_nm].geo_x,
                  "lon" : s_meta[t_st_nm].geo_y
                },
                "people":{
                  "in" : people_in,
                  "out" : people_out,
                  "total" : people_in+people_out
                }
              }
            } else {
              s_logs = {
                "@timestamp" : ldate,
                "code": dataIn[2],
                "line_num" : dataIn[1],
                "line_num_en" : line_num_lang[dataIn[1]],
                "station": {
                  "name" : stn_nm_full
                },
                "location" : {
                  "lat" : s_meta[t_st_nm].geo_x,
                  "lon" : s_meta[t_st_nm].geo_y
                },
                "people":{
                  "in" : people_in,
                  "out" : people_out,
                  "total" : people_in+people_out
                }
              }
            }
    
            // if( t_st_nm.indexOf("구파발") > -1 ) { console.log(s_logs); }
            // console.log(s_logs);
            //console.log(ldate.toISOString().slice(0,10).replace(/-/g,""));
            // var fileName = "1to4_"+ldateTemp[0]+ldateTemp[1]+ldateTemp[2]+".log";
            //var fileName = "1to4_"+ldate.toISOString().slice(0,10).replace(/-/g,"")+".log";
            var logdata = JSON.stringify(s_logs)+"\n";
            
            // data 디렉토리 아래 저장할 파일 이름. data 디렉토리 없으면 생성해야 함
            fs.appendFileSync("data/seoul-metro-2018.logs", logdata);
          }
    
        }
    
      }
    
    });
    • 변환 프로그램 실행
    $ cd /elastic-demos/seoul-metro-logs
    
    $ node bin/run.js
    • 만들어진 로그 데이터 확인
    $ cd /elastic-demos/seoul-metro-logs/data
    
    $ ls 
    seoul-metro-2018.logs
    
    $ wc -l seoul-metro-2018.logs
    2007500 seoul-metro-2018.logs

    3. Logstash 를 이용해서 Elasticsearch 로 색인

    Logstash 설정

    • 출력테스트
    $ cd elastic-demos/seoul-metro-logs/config
    $ vi seoul-metro-logs.conf
    
    ## 위에서 생성한 log 데이터 위치 정확히 기입
    input {
      file {
        path => "/root/elastic-demos/seoul-metro-logs/data/seoul-metro-2018.logs"
        codec => "json"
        start_position => "beginning"
        sincedb_path => "/dev/null"
      }
    }
    
    filter {
      mutate {
        remove_field => ["host","path","@version"]
      }
    }
    
    output {
      stdout { }
    }
    • Logstash로 log파일 elasticsearch에 전송하기 위한 설정 변경
    $ cd elastic-demos/seoul-metro-logs/config
    $ vi seoul-metro-logs.conf
    
    ## 위에서 생성한 log 데이터 위치 정확히 기입
    input {
      file {
        path => "/root/elastic-demos/seoul-metro-logs/data/seoul-metro-2018.logs"
        codec => "json"
        start_position => "beginning"
        sincedb_path => "/dev/null"
      }
    }
    
    filter {
      mutate {
        remove_field => ["host","path","@version"]
      }
    }
    
    output {
      #stdout { }
    
      # 환경변수 설정:
      # $LS_HOME/config/startup.options 또는
      # $LS_HOME/bin/logstash-keystore
    
      elasticsearch {
        hosts => ["localhost:9200"]
        index => "seoul-metro-logs-2018"
      }
    }
    • 전송
    $ /usr/share/logstash/bin/logstash -f /root/elastic-demos/seoul-metro-logs/config/seoul-metro-logs.conf
    
    ## 실행 결과
    Using JAVA_HOME defined java: /usr/lib/jvm/java-8-openjdk-amd64
    WARNING, using JAVA_HOME while Logstash distribution comes with a bundled JDK
    WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
    Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
    [INFO ] 2021-07-31 01:06:41.175 [main] runner - Starting Logstash {"logstash.version"=>"7.13.2", "jruby.version"=>"jruby 9.2.16.0 (2.5.7) 2021-03-03 f82228dc32 OpenJDK 64-Bit Server VM 25.292-b10 on 1.8.0_292-8u292-b10-0ubuntu1~18.04-b10 +indy +jit [linux-x86_64]"}
    [WARN ] 2021-07-31 01:06:41.540 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
    [INFO ] 2021-07-31 01:06:42.695 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9601}
    [INFO ] 2021-07-31 01:06:43.398 [Converge PipelineAction::Create<main>] Reflections - Reflections took 43 ms to scan 1 urls, producing 24 keys and 48 values 
    [WARN ] 2021-07-31 01:06:44.604 [Converge PipelineAction::Create<main>] elasticsearch - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode.
    [INFO ] 2021-07-31 01:06:44.696 [[main]-pipeline-manager] elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["//localhost:9200"]}
    [INFO ] 2021-07-31 01:06:45.180 [[main]-pipeline-manager] elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://localhost:9200/]}}
    [WARN ] 2021-07-31 01:06:45.366 [[main]-pipeline-manager] elasticsearch - Restored connection to ES instance {:url=>"http://localhost:9200/"}
    [INFO ] 2021-07-31 01:06:45.563 [[main]-pipeline-manager] elasticsearch - Elasticsearch version determined (7.13.2) {:es_version=>7}
    [WARN ] 2021-07-31 01:06:45.565 [[main]-pipeline-manager] elasticsearch - Detected a 6.x and above cluster: the `type` event field won't be used to determine the document _type {:es_version=>7}
    [INFO ] 2021-07-31 01:06:45.784 [Ruby-0-Thread-10: :1] elasticsearch - Using a default mapping template {:es_version=>7, :ecs_compatibility=>:disabled}
    [INFO ] 2021-07-31 01:06:45.859 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>1000, "pipeline.sources"=>["/root/elastic-demos/seoul-metro-logs/config/seoul-metro-logs.conf"], :thread=>"#<Thread:0x52f14142 run>"}
    [INFO ] 2021-07-31 01:06:46.981 [[main]-pipeline-manager] javapipeline - Pipeline Java execution initialization time {"seconds"=>1.12}
    [INFO ] 2021-07-31 01:06:47.296 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"}
    [INFO ] 2021-07-31 01:06:47.392 [Agent thread] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
    [INFO ] 2021-07-31 01:06:47.488 [[main]<file] observingtail - START, creating Discoverer, Watch with file and sincedb collections

    kibana에서 데이터 확인하고 전체 데이터 전송하기 위해 ctrl + c 로 전송 끊어줌

     

    • Kibana에서 데이터 확인

    명령어 한번 씩 쳐보면서 데이터 확인

    • Remapping

    1) 깔끔하게 보이기 위해

    2) 인데스를 최적화 하기 위해

    → text 타입으로 저장하면, 저장 인덱스만 늘어나기 때문에 용량 차지 많고, 성능 떨어짐

    • mapping 전, elastic search에 nori-tokenizer 사용

    → "홍대입구"라고 치면 데이터가 출력되는데 "홍대"라고 치면 데이터가 출력되지 않음

    → 이러한 문제를 보안하기 위해 nori-tokenizer 사용

    • nori-tokenizer 설치 전, elastic search 설정 변경
    ##elasticsearch.yml에서 discovery설정 바꿔주어야 함
    
    $ cd /etc/elasticsearch
    $ vi elasticsearch.yml
    
    # --------------------------------- Discovery ----------------------------------
    #
    # Pass an initial list of hosts to perform discovery when this node is started:
    # The default list of hosts is ["127.0.0.1", "[::1]"]
    #
    discovery.seed_hosts: ["127.0.0.1", "[::1]"]
    #wget으로 엘라스틱 서치 설치했을 때 default 경로
    $ cd /usr/share/elasticsearch/bin
    $ ./elasticsearch-plugin install analysis-nori
    
    warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME
    Future versions of Elasticsearch will require Java 11; your Java version from [/usr/lib/jvm/java-8-openjdk-amd64/jre] does not meet this requirement. Consider switching to a distribution of Elasticsearch with a bundled JDK. If you are already using a distribution with a bundled JDK, ensure the JAVA_HOME environment variable is not set.
    -> Installing analysis-nori
    -> Downloading analysis-nori from elastic
    [=================================================] 100%   
    -> Installed analysis-nori
    -> Please restart Elasticsearch to activate any plugins installed
    
    #서비스 재시작
    $ sudo systemctl restart elasticsearch.service
    • Mapping & Template 생성

    → 단, search시에는 standard 사용

     

    → 복합어를 붙여서 검색하기 위해 shingle 사용

    PUT _template/seoul-metro
    {
      "order": 5,
      "index_patterns": [
        "seoul-metro-logs*"
      ],
      "settings": {
        "number_of_shards": 2,
        "analysis": {
           "analyzer": {
            "nori": {
              "tokenizer": "nori_t_discard",
              "filter": "my_shingle"
            }
          },
          "tokenizer": {
            "nori_t_discard": {
              "type": "nori_tokenizer",
              "decompound_mode": "discard"
            }
          },
          "filter": {
            "my_shingle": {
              "type": "shingle",
              "token_separator": "",
              "max_shingle_size": 3
            }
          }
        }
      }, 
      "mappings" : {
          "properties" : {
            "@timestamp" : {
              "type" : "date"
            },
            "code" : {
              "type" : "keyword"
            },
            "line_num" : {
              "type" : "keyword"
            },
            "line_num_en" : {
              "type" : "keyword"
            },
            "location" : {
              "type": "geo_point"
            },
            "people" : {
              "properties" : {
                "in" : {
                  "type" : "integer"
                },
                "out" : {
                  "type" : "integer"
                },
                "total" : {
                  "type" : "integer"
                }
              }
            },
            "station" : {
              "properties" : {
                "ch" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "chc" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "en" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "jp" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "kr" : {
                  "type" : "text",
                  "fields" : {
                    "nori" : {
                      "type" : "text",
                      "analyzer" : "nori",
                      "search_analyzer" : "standard"
                    },
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "name" : {
                  "type" : "text",
                  "fields" : {
                    "nori" : {
                      "type" : "text",
                      "analyzer" : "nori",
                      "search_analyzer" : "standard"
                    },
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                }
              }
            }
          }
        }  
    }

    • reindex

    ?wait_for_completion=false 를 붙여주지 않으면 timeout 오류 발생

    → Reindex API 호출은 기본적으로 백그라운드 재색인 작업이 완료되기를 기다리지만, Kibana에서 이것을 호출하는 경우 Kibana는 30s표시 에서 요청을 중단하기 때문

    POST _reindex?wait_for_completion=false
    {
      "source": {
        "index": "seoul-metro-logs-2018"
      },
      "dest": {
        "index": "seoul-metro-logs-temp"
      }
    }

    처리과정 확인

    GET _tasks?actions=*reindex&detailed

     

    • 토크나이저 적용 확인
    GET seoul-metro-logs-temp/_search
    {
      "query": {
        "match": {
          "station.name.nori": "홍대"
        }
      }
    }

    • 데이터 전송 확인
    GET seoul-metro-logs*/_count

    728x90

    댓글

Designed by Tistory.