본문 바로가기

Tech Stack/Elasticsearch

우리FISA AI 엔지니어링 Elasticsearch - 1

엘라스틱 환경 접속

 

엘라스틱 서치에서

Elasticsearch, Kibana를 설치.
jvm.options에서
33번째 줄 주석 제거 후
-Xms1g
-Xms1g
로 변경

elasticsearch.yml
끝에

cluster.name: woori-es
node.name: woori-es-node01

path:
  data: C:\ITStudy\ELK\elasticsearch\data
  logs: C:\ITStudy\ELK\elasticsearch\logs  

network.host: 127.0.0.1

discovery.type: "single-node"
xpack.security.enabled: false
작성

----

 

rver.port: 5601
server.host: localhost
server.publicBaseUrl: "http://localhost:5601"
elasticsearch.hosts: ["http://localhost:9200"]

kibana.yml 끝쪽에 입력

 

Explore on my own

- > Try sample data

 -- > 세 샘플 모두 ADD

 

Elasticsearch 사용

  • CREATE - POST
  • READ(RETRIVE) - GET, HEAD
  • UPDATE - PUT(통으로 수정하는 것), PATCH(일부만 수정하는 것)
  • DELETE - DELETE

 

규약.

페이지 이름

값을 조회하기 위해서 본문 내용이아니라, 주소에다가 0번 dir 1 page 에 그룹 아이디까지 한 후 어떤 자료를 보낼건지,

 

 

CRUD

 

 

 

"나는 파전을 먹는다"  keyword자료형   통으로 1에 넣어서 관리하는 방식

 

text자료형

명사       명사에 매겨진  숫자  doc 번호

나 1         1                                1

파전 2     2                                1

 

 

# CREATE
PUT [인덱스 이름]/_doc/[_id값]  # ID값을 직접 부여
{
  [문서 내용]
}

#삽입
PUT my_index/_doc/1
{
  "title": "hello world",
  "views": 1234,
  "public": true,
  "created": "2019-01-17T14:05:01.234Z"
}

# PUT - 전부가 아니라 일부를 변경하는 방식 doc id까지 같이 넣어야 함
#POST - 삽입 -> 
#doc id가 없으면 난수로 생성
PUT my_index/_doc/
{
  "title": "world hello world 234"
}

POST my_index/_doc/
{
  "title": "world hello world 234"
}

GET my_index/_doc/234


#doc번호를 생성하는 경우 - 수정할 일이 많음
#doc번호를 생성하지 않는 경우 - 수정할 필요가 없음(로그 수정, 생성되고있는 정보 보관용)

POST [인덱스 이름]/
{
  ID자동생성 [문서 내용]
}

# READ(RETRIEVE)
GET [인덱스 이름]/_doc/[_id값]

# UPDATE
POST [인덱스 이름]/_update/[_id값]
{
  "doc": {
    [문서 내용]
  }
}

#내용의 일부만 본문에 달아서 수정할 때는 _update
POST my_index/_update/1
{
  "doc": {
    "title": "hello elasticsearch!"
  }
}

# DELETE 
DELETE [인덱스 이름]/_doc/[_id값]

GET my_index/_search/
{
  "query": {
    "match": {
      "title": "hello"
    }
  }
}

GET my_index/_search/
{
  "query": {
    "match_all": {
    }
  }
}

#match_all 생략된 상태
GET my_index/_search/

#match_phrase 입력된 순서를 고려해서(문맥)대로 검색한다.
GET my_index/_search/
{
 "query": {
   "match_phrase": {
     "title": "world hello"
   }
 } 
}

GET my_index/_search/
{
 "query": {
   "query_string": {
     "default_field": "title",
     "query": "world hello"
   }
 } 
}

GET my_index/_search?q=title:world

GET my_index/_search?q=title:world hello


PUT array_test
	{
		"mappings": {
			"properties": {
				"longField": {
				"type": "long"
				},
				"keywordField": {
					"type": "keyword"
				}
			}
		}
}

GET array_test

#실습: array_test의 
#1번 문서의 longField에는 123, keywordField에는 [”this”, “is”, “it”]을,
POST array_test/_doc/1
{
  "longField" :123,
  "keywordField" : ["this", "is", "it"]
}
GET array_test/_doc/1


#2번 문서의 longField에는 [1, 2, 3], keywordField에는 ”this is it”을,
POST array_test/_doc/2
{
  "longField" : [1, 2, 3],
  "keywordField" : "this is it"
}
GET array_test/_doc/2
#3번 문서의 longField에는 [1, ‘2’, 3], keywordField에는 [”this is it”, 1]을 인덱싱(색인)해보세요
POST array_test/_doc/3
{
  "longField" : [1, "2", 3],
  "keywordField" : ["this is it", 1]
}

GET array_test/_doc/


POST array_test/_doc/4
{
  "longField" : "2",
  "keywordField" : 123
}

GET array_test/_doc/4


#NoSql특징 -> 데이터가 많아 졌을 때 세세한 정합성을 지키다보니 에러가 남. 그래서 예외를 많이 허용한 것.

GET array_test/_doc/3
# NoSQL의 특징 -> 데이터가 너무 많아지면 세세한 정합성을 지키다가 에러가 나는 경우가 많습니다. 그래서 예외를 많이 허용한다. 

POST woorifisa/_doc/
{
  "student": {
    "name": "신짱구",  # student.name  메모리 
    "age": 5     # student.age  메모리 
  }
}

GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name": "짱구"
    }
  }
}
}
#내부적으로 평탄화해서 관리하는 object자료형
#text자료형으로 검색
#역색인지 보통은 영어가 아닌 경우 띄어쓰기 단위로 토큰을 발행합니다.
POST woorifisa/_doc/


GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name": "신짱구"  #text자료형으로 검색
    }
  }
}

GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name.keyword": "짱구"
    }
  }
}








# 내부적으로 평탄화해서 관리하는 object 자료형 
# text 자료형으로 검색
# 역색인시 보통은 영어가 아닌 경우 띄어쓰기 단위로 토큰 발행합니다 
GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name": "짱구"  } 
  }
}

# keyword 자료형으로 검색 - 통째로 검색
GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name.keyword": "짱구"  }
  }
}

# woorifisa에 여러분 이름을 넣어서 2번 doc 생성
# name: 장 정우

POST woorifisa/_doc/2
{
  "Student":{
    "name": "장 정우",
    "age" : 26
  }
}

GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name.keyword": "장 정우"
    }
  }
}


POST woorifisa/_doc/3
{
  "Student":{
    "name": "This's my name",
    "age" : 26
  }
}

# 알파벳
# 소문자, 대문자 구분은 하지 않음
# 토크나이징 방법을 임의로 지정하지 않으면 띄어쓰기 단위
GET woorifisa/_search
{
  "query": {
    "match": {
      "student.name": "This's my"
    }
  }
}


GET woorifisa/_mapping

# NESTED 타입 배열의 두번째 방법
# 별도의 두개의 doc룰 내부적으로 엮어서 한 장처럼 활용

PUT woorifisa_nested_test
{
  "mappings": {
    "properties": {
      "student": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "keyword"
          },
          "age": {
            "type": "long"
          }
        }
      }
    }
  }
}

GET woorifisa_nested_test/_mapping

POST woorifisa_nested_test/_doc/
{
  "student": {
    "name": "신짱구", 
    "age": 5
  }
}

POST woorifisa_nested_test/_doc/2
{
  "student": {
    "name": "장 정우",  
    "age": 5  
  }
}

#에러가 아니라 없음으로 결과가 출력됨
#nested타입과 object타입은 다른 쿼리로 검색을 한다.
POST woorifisa_nested_test/_doc/2
{
  "student": {
    "name": "장 정우",  
    "age": 5  
  }
}


GET woorifisa_nested_test/_search
{
  "query": {
    "nested": {
      "path": "student",
      "query": {
        "match": {
        "student.name": "장 정우"
      }}
    }
  }
}

# _bulk라는 명령어를 사용하면 데이터를 한꺼번에 집어 넣을 수 있습니다.
POST _bulk/
{"index": {"_index" : "test", "_id":"1"}}{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
{"index":{"_index" : "test", "_id":"6"}}{"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
{"index":{"_index" : "test", "_id":"13"}}
{"account_number":13,"balance":32838,"firstname":"Nanette","lastname":"Bates","age":28,"gender":"F","address":"789 Madison Street","employer":"Quility","email":"nanettebates@quility.com","city":"Nogal","state":"VA"}
{"index":{"_index" : "test", "_id":"18"}}
{"account_number":18,"balance":4180,"firstname":"Dale","lastname":"Adams","age":33,"gender":"M","address":"467 Hutchinson Court","employer":"Boink","email":"daleadams@boink.com","city":"Orick","state":"MD"}
{"index":{"_index" : "test", "_id":"20"}}
{"account_number":20,"balance":16418,"firstname":"Elinor","lastname":"Ratliff","age":36,"gender":"M","address":"282 Kings Place","employer":"Scentric","email":"elinorratliff@scentric.com","city":"Ribera","state":"WA"}
{"index":{"_index" : "test", "_id":"25"}}
{"account_number":25,"balance":40540,"firstname":"Virginia","lastname":"Ayala","age":39,"gender":"F","address":"171 Putnam Avenue","employer":"Filodyne","email":"virginiaayala@filodyne.com","city":"Nicholson","state":"PA"}
{"index":{"_index" : "test", "_id":"32"}}
{"account_number":32,"balance":48086,"firstname":"Dillard","lastname":"Mcpherson","age":34,"gender":"F","address":"702 Quentin Street","employer":"Quailcom","email":"dillardmcpherson@quailcom.com","city":"Veguita","state":"IN"}


GET test/_search


# my_bulk라는 인덱스에 집어넣어 주세요 
POST my_bulk/_bulk
{"index":{"_id":1}}
{"message":"죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를"}
{"index":{"_id":2}}
{"message":"죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를, 잎새에 이는 바람에도 나는 괴로워했다"}
{"index":{"_id":3}}
{"message":"죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를,\n 잎새에 이는 바람에도 너는 괴로워했다"}
{"index":{"_id":4}}
{"message":"chrome google Chrome Google"}
{"index":{"_id":5}}
{"message":"하늘사 Google Chrome"}
{"index":{"_id":6}}
{"message":"pink"}
{"index":{"_id":7}}
{"message":"pinkRed"}
{"index":{"_id":8}}
{"message":"pink red blue"}
{"index":{"_id":9}}
{"message":"pink red blue black"}
{"index":{"_id":10}}
{"message":"pink red blue black green"}
{"index":{"_id":11}}
{"message":"pink blue red black green"}
{"index":{"_id":12}}
{"message":"pink pink"}



# match_all, match, match_phrase, query_string
# 띄어쓰기는 OR 을 의미합니다
# 단어 사이에 AND를 넣으면 A AND B A도 있고 B도 있어야만 검색 가능 
# test 인덱스에서 address 필드에 Madison 가 에 사는 사람이 누구인지,  Madison Street 에 사는 사람이 누군지 찾아주세요.

# match_all, match, match_phrase, query_string

# 띄어쓰기는 OR 을 의미합니다
# query_string에서 단어 사이에 AND를 넣으면 A AND B A도 있고 B도 있어야만 검색 가능 
# test 인덱스에서 address 필드에 Madison 가 에 사는 사람이 누구인지,  Madison Street 에 사는 사람이 누군지 찾아주세요.
GET test/_search
{ "query": {
  "match": {
    "address": "Madison Street"
    }
  }
}

GET test/_search
{ "query": {
  "match_phrase": {
    "address": "Madison Street"
    }
  }
}

# 전문검색(Full Text)
# 범용적인 방법 

# default_field  옵션은 필드 규제 
GET test/_search
{ "query": {
  "query_string": {
    "default_field": "lastname", 
    "query": "Nanette"
    }
  }
}

GET test/_search
{ "query": {
  "query_string": {
    "fields": ["firstname", "lastname"], 
    "query": "Nanette"
    }
  }
}
GET test/_search
{ "query": {
  "query_string": {
    "query": "Madison AND Street"
    }
  }
}


# 1. 나이가 34살이면서 여성인 사람 
# must 내부 조건이 2개이므로 [ ](배열)로 감싸줍니다
GET test/_search
{
  "query": {
    "bool": {
      "must":[{
        "match": {
          "age":34
          }
        },
        {"match":{
          "gender":"F"
          }
        }
        ]
    }
  }
}


# 나이가 34살이면서 firstname이 Diallard
# bool - must
# 소문자도 가능
GET test/_search
{
  "query": {
    "bool": {
      "must":[{
        "match": {
          "age":34
          }
        },
        {"match":{
          "firstname":"dillard"
          }
        }
        ]
    }
  }
}

# 나이가 34살이면서 성별이 F가 아닌사람
?????


GET test/_search
{
  "query": {
    "bool": {
      "must":[{
        "match": {
          "age":34
          }
        },
        {"match":{
          "gender":"M"
          }
        }
        ]
    }
  }
}


# 3. balance가 30000보다 많은 사람
GET test/_search
{
  "query":{
    "bool":{
      "must": [
        {"range":{
            "balance": {
              "gte": 30000
            }
          }
        }]
    }
  }
}

# 4. balance가 30000보다 많으면서 Dillad가 아닌 사람

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "balance": {
              "gte": 30000
            }
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "firstname": "Dillard"
          }
        }
      ]
    }
  }
}

# eq(must - match) ne(must not - match)로 해결가능하기에 equal과 not equal은 동작하지 않습니다. 
# gt > lt < 

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "balance": {
              "eq": 39225
            }
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "firstname": "Dillard"
          }
        }
      ]
    }
  }
}



# 5. balance가 30000보다 높으면서(must) state가 PA인 경우에 가중치 (should)
# should와 일치하지 않는다고 걸러지는 것은 아님
GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {"range": {
          "balance": {
            "gte": 30000
          }
        }}
      ],
      "should": [
        { "match": {
          "state": "PA"
        }}
      ]
    }
  }
}

# 6. balance가 30000보다 높으면서 state가 PA인 경우를 검색하되 score에는 영향을 주지 않음(filter)
# 점수 계산 시간 단축 - 속도 빠름
GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {"range": {
          "balance": {
            "gte": 30000
          }
        }}
      ],
      "filter": [
        { "match": {
          "state": "PA"
        }}
      ]
    }
  }
}

# Must not처럼 걸러냅니다. 대신 점수에는 영향을 미치지 않습니다.
# 7. balance가 30000보다 높은 사람을 검색하되 score에는 영향을 주지 않으면서 age가 27인 경우 (filter) 
GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {"range": {
          "balance": {
            "gte": 30000
          }
        }}
      ],
      "should": [
        { "match": {
          "age": 27
        }}
      ]
    }
  }
}

# sholud 는 해당 경우에 대해 점수를 올려줍니다
# filter는 해당 경우만 걸러내되 점수에는 영향을 주지 않습니다

# sql의 와일드카드와 비슷한 기능을 제공합니다.
# * : 0개 이상의 모든 글자
# ? : ? 1개당 한 글자
GET test/_search
{
  "query": {
    "query_string": {
      "default_field": "state",
      "query": "?L"
    }
  }
}

# D로 firstname이 시작하는 사람
# D로 firstname이 시작하는 4글자의 사람
GET test/_search
{ "query": {
  "query_string": {
    "default_field": "firstname", 
    "query": "D*"
    }
  }
}
#field와 default_field의 차이
#default_field 딱 하나의 필드에서만
#field는 두개 이상의 필드에서 찾기

GET test/_search
{ "query": {
  "query_string": {
    "default_field": "firstname", 
    "query": "D???"
    }
  }
}

# 내부적으로는 와일드카드를 꼭 필요하면 쓰지만 외부에서 접속해야하는 경우에 대해서는 권장하지 않습니다. (서버 과부하 우려)
# D로 시작하는 모든 사람 탐색
# D로 시작하는 4글자의 사람