[ 기초부터 다지는 ElasticSearch 운영 노하우] 2장. ElasticSearch 기본 동작

eunsol Jo·2021년 8월 24일
0
post-thumbnail
  • 문서 색인/조회/삭제
  • 인덱스 생성/삭제
  • 문서 검색/분석

2.1 문서 색인과 조회

문서 색인하기

    # request
    curl -X PUT "localhost:9200/user/_doc/1?pretty" -H 'Content-Type: application/json' -d'{ "username" : "esjo" }'

    # response
    {
      "_index" : "user",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "result" : "created",
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "_seq_no" : 0,
      "_primary_term" : 1
    }

    # curl -X [PUT|POST|DELETE|GET] "IP:PORT/인덱스/타입/문서ID" ...
    
    # 인덱스(user) → 문서를 저장하는 가장 큰 논리적인 단위. 
    # 타입(_doc) → 인덱스:타입 = 1:1 (버전6.X이후, 5.x버전에서는 멀티타입지원됨)
    # ID(1) → 문서ID는 인덱스내 유일해야함

    # 내부적으로 인덱스 생성 + 문서색인 + 스키마 생성 등의 동작을 한다.
    # 색인시 인덱스/타입/스키마가 없으면 생성. 있다면 스키마 정합성 체크, 문서ID가 있다면 기존문서 업데이트

curl 옵션 리스트
-X [HTTP메소드]
-H [헤더]
-d [데이터]

문서 조회하기

    # request
    curl -X GET "localhost:9200/user/_doc/1?pretty"

    # response - 문서있음
    {
      "_index" : "user",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "_seq_no" : 0,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {  # 문서내용
        "username" : "esjo"
      }
    }

    # response - 문서없음
    {
      "_index" : "user",
      "_type" : "_doc",
      "_id" : "1",
      "found" : false
    }

문서 삭제하기

    # request
    curl -X DELETE "localhost:9200/user/_doc/1?pretty"

    # response
    {
      "_index" : "user",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 2,
      "result" : "deleted", # 문서삭제
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "_seq_no" : 1,
      "_primary_term" : 1
    }

인덱스 생성

    # request
    curl -X PUT "localhost:9200/contents?pretty"

    # response
    {
      "acknowledged" : true,
      "shards_acknowledged" : true,
      "index" : "contents"
    }

인덱스 확인

    # request
    curl -s http://localhost:9200/_cat/indices?v

    # response
    health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   contents TlSDCNH8Rc6-TIzm6z8QCg   1   1          0            0       208b           208b
    yellow open   user     if4yeNYCTf6ew04xpp0-9Q   1   1          0            0       228b           228b

문서색인

    # request
    curl -X PUT "localhost:9200/contents/_doc/1?pretty" -H 'Content-Type: application/json' -d'{"title": "How to use ES", "author": "esjo"}'

    # response
    ...   "result" : "created", # 문서생성 ...

문서수정

    # request
    curl -X PUT "localhost:9200/contents/_doc/1?pretty" -H 'Content-Type: application/json' -d'{"title": "How to use ES", "author": "eunsol.jo"}'

    # reponse
    ...   "result" : "updated",  # 문서수정 ...

스키마 확인

    # request
    curl -s http://localhost:9200/contents/_mappings?pretty

    # 아래처럼 해도 결과 동일함
    # curl -s "http://localhost:9200/contents/_mappings?pretty"
    # curl -X GET "http://localhost:9200/contents/_mappings?pretty"
    # curl -X GET http://localhost:9200/contents/_mappings?pretty

    # response
    {
    "contents" : {
        "mappings" : {
          "properties" : {
            "author" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "title" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        }
      }
    }

스키마 동적 수정

    # request
    curl -X PUT "localhost:9200/contents/_doc/2?pretty" -H 'Content-Type: application/json' -d'{"title": "How to use Nginx", "author": "eunsol.jo", "rating" : 5.0}'

    # reponse
    ... "rating" : { "type" : "float" } ...

    # rating이라는 새로운 필드 입력시 동적으로 스키마가 수정됨. (정상등록)

스키마 정합성 체크

    #request
    curl -X PUT "localhost:9200/contents/_doc/2?pretty" -H 'Content-Type: application/json' -d'{"title": "How to use Nginx", "author": "eunsol.jo", "rating" : "N/A"}'
    
    # response
    {
      "error" : {
        "root_cause" : [
          {
            "type" : "mapper_parsing_exception",
            "reason" : "failed to parse field [rating] of type [float] in document with id '2'. Preview of field's value: 'N/A'"
          }
        ],
        "type" : "mapper_parsing_exception",
        "reason" : "failed to parse field [rating] of type [float] in document with id '2'. Preview of field's value: 'N/A'",
        "caused_by" : {
          "type" : "number_format_exception",
          "reason" : "For input string: \"N/A\""
        }
      },
      "status" : 400
    }

    # 스키마 동적 생성이후 맞지 않는 데이터타입 입력시 에러 (rating에 문자열 "N/A" 입력시도)

2.2 문서 검색하기

데이터색인

    # request : bulk - json파일
    curl -H "Content-Type: application/json" -XPOST "localhost:9200/books/_doc/_bulk?pretty&refresh" --data-binary "@books.json"

    # books.json파일
    {"index":{"_id":"3"}}
    {"doc":{"title": "book3", "author": "eunsol.jo3", "rating" : 3.0}}
    {"index":{"_id":"4"}}
    {"doc":{"title": "book4", "author": "eunsol.jo4", "rating" : 4.0}

    # response
    {
      "took" : 324,
      "errors" : true,
      "items" : [
        {
          "index" : {
            "_index" : "books",
            "_type" : "_doc",
            "_id" : "3",
            "_version" : 1,
            "result" : "created",
            "forced_refresh" : true,
            "_shards" : {
              "total" : 2,
              "successful" : 1,
              "failed" : 0
            },
            "_seq_no" : 0,
            "_primary_term" : 1,
            "status" : 201
          }
        },
        {
          "index" : {
            "_index" : "books",
            "_type" : "_doc",
            "_id" : "4",
            "status" : 400,
            "error" : {
              "type" : "mapper_parsing_exception",
              "reason" : "failed to parse",
              "caused_by" : {
                "type" : "json_e_o_f_exception",
                "reason" : "Unexpected end-of-input: expected close marker for Object (start marker at [Source: (ByteArrayInputStream); line: 1, column: 1])\n at [Source: (ByteArrayInputStream); line: 1, column: 66]"
              }
            }
          }
        }
      ]
    }

문서조회 - 퀴리(포함여부) + 필터(T/F)

    # request
    # 쿼리 - 전체조회
    curl -X GET "localhost:9200/books/_search?q=*&pretty"
    # 쿼리 - 문자열포함
    curl -X GET "localhost:9200/books/_search?q=eunsol.jo4&pretty"
    # 필터 - 필드조건
    curl -X GET "localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d
    					# match
    					'{"query":{"match":{"rating" : 3.0}}}'
    					# gte
    					'{"query":{"bool":{"must":{"match_all":{}}, "filter":{"range":{"rating":{"gte": 2.0}}}}}}'

    # response - 전체
    {
      "took" : 78, # 소요시간
      "timed_out" : false,
      "_shards" : {
    	    "total" : 1, # 샤드수
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 2, # 문서수
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "books",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "doc" : {
                "title" : "book3",
                "author" : "eunsol.jo3",
                "rating" : 3.0
              }
            }
          },
          {
            "_index" : "books",
            "_type" : "_doc",
            "_id" : "4",
            "_score" : 1.0,
            "_source" : {
              "doc" : {
                "title" : "book4",
                "author" : "eunsol.jo4",
                "rating" : 4.0
              }
            }
          }
        ]
      }
    }

2.3 문서 분석하기

aggregation


    curl -X GET "localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d'
    {
    	"size": 0,
    	"aggs": {
    		"group_by_state": {
    			# author에 나오는 단어 빈도
    			"terms": {
    				"field": "author.keyword"
    			}
    			# rating 평균내기
    			"aggs": {
    				"average_ratings": {
    					"avg": {
    						"field": "ratings"
    					}
    				}
    			}
    		}
    	}
    }
    '
  • 분석작업은 보통 Kibana or Grafana 와 같은 시각툴을 이용.
  • 시각툴 사용시 힙영역 사용에 유의하여, 전체 클러스터 서비스에 영향을 주지 않도록 한다.
profile
Later never comes 👩🏻‍💻

1개의 댓글

comment-user-thumbnail
2022년 12월 21일

혹시 중간에 bulk로 입력하셨을 때, "Unexpected end-of-input: expected close marker for Object" 가 뜨는 이유가 뭔지 아시나요?ㅠ

답글 달기