# [Elasticsearch] Elasticsearch 기본용어와 CRUD 명령어

![](https://blog.kakaocdn.net/dna/byZh0q/dJMcah4r0Wi/AAAAAAAAAAAAAAAAAAAAAEaZOs2uJIkaXNIZwffG9FziQ6DPh2uxpknHI6847OhS/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=nn9jYCpE%2Byrq4jT%2Fp%2FzBCYN8eqw%3D align="left")

\-elastic

## ▶ 들어가며

이번 글에서는 Elasticsearch를 공부하면서 가장 먼저 익혀야 하는 **기본 용어**를 정리하고,  
직접 코드를 쳐가며 **CRUD(Create / Read / Update / Delete)** 명령어에 익숙해지는 시간을 가져보려고 한다.

Elasticsearch는 처음 보면 생소한 용어가 많아서 막막할 수 있는데,  
사실 구조적으로는 우리가 익숙한 MySQL과 닮은 부분이 굉장히 많다.

둘 다 데이터베이스라는 큰 틀 안에서

* 데이터를 삽입하고(Create)
    
* 조회하고(Read)
    
* 수정하고(Update)
    
* 삭제(Delete)
    

하는 흐름은 동일하다.

그래서 이번 글에서는  
👉 MySQL과 비교하면서 Elasticsearch를 이해하는 방식으로 정리해보려고 한다!!

---

## ▶ Elasticsearch 기본 용어 정리

아래는 가장 기본적인 MySQL 과의 대응 관계이다.

![](https://blog.kakaocdn.net/dna/73BoU/dJMcacB4Kl8/AAAAAAAAAAAAAAAAAAAAANmFOi6ii-LtayHddIcHT3Kvy7kl6fFSsqoJUAzXQu-e/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=ixeT5lpm2QlHmlS6wW5YGqB2VzY%3D align="left")

\-기본 용어 정리

MySQL:

> **table을 만들고 → column의 schema를 정의하고 → row(record)를 저장하고 → 데이터를 조회/수정/삭제한다**

⭐Elasticsearch:

> **인덱스를 만들고 → field의 mapping을 정의하며 → document를 저장하고 → 데이터들을 검색/수정/삭제한다**

라는 구조로 동작하는 것이다.

---

## ▶ CRUD 명령어 정리

이제부터는 Elasticsearch에서 실제로 사용하는 CRUD 명령어를 직접 쳐보면서 익혀보자!!  
이번 글에서는 앞으로 계속 사용할 기본 **인덱스명을 "users"**로 고정해서 진행한다.

#### \- Index 생성하기

MySQL에서 CREATE TABLE을 하듯이, Elasticsearch에서는 데이터를 저장하기 위한 **Index**를 생성한다.

아래 명령어로 users 인덱스를 생성해 보자.

```plaintext
PUT /users
```

![](https://blog.kakaocdn.net/dna/NYhMq/dJMcaajX4L6/AAAAAAAAAAAAAAAAAAAAAHwI6Zixd-1q7q06_Mmx2-Y8RWX11cTqrZciTtnMHGBQ/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=UQQDDKQvQlXLgebSAfzfwi9m57w%3D align="left")

---

#### \- Index 조회하기

생성한 인덱스가 존재하는지 확인하는 명령어이다.

```plaintext
GET /users
```

![](https://blog.kakaocdn.net/dna/cEhmUK/dJMcaiPMalC/AAAAAAAAAAAAAAAAAAAAAP5egshosvacbmpOPVc-vXWPVeEmu2RvNMW0WTaKobN4/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=I5Wdoz%2BprkkwriJKkfEBJ%2FuJmeA%3D align="left")

---

#### \- Index 삭제하기

이번에는 인덱스를 삭제해보자.

```plaintext
DELETE /users
```

![](https://blog.kakaocdn.net/dna/czQPN3/dJMcadt91xp/AAAAAAAAAAAAAAAAAAAAAH-iAcXFgzH2IsvL4RAiIsl-qjl_fb7MqW58qfeHD-sS/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=bzOPHT72d9VZKt%2BDKh11cygrmLU%3D align="left")

이 상태에서 다시 인덱스를 조회해보면

![](https://blog.kakaocdn.net/dna/bct2Jk/dJMcafS6P3I/AAAAAAAAAAAAAAAAAAAAALynFs2moDhz4LHbvxLWVvZVG41zL7tU9i-C32H_7klL/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=8T%2BFjjRyQL7Gh3HwpvXziNcyImM%3D align="left")

"index\_not\_found\_exception" 에러가 발생한다

👉 즉, 인덱스가 삭제되었기 때문에 **더 이상 존재하지 않는 상태**임을 확인할 수 있다!

---

#### \- Mapping 정의하기

MySQL에서 테이블을 만들 때 schema를 정의하듯이, Elasticsearch에서도 index 내부에 어떤 타입의 데이터를 저장할지 정의할 수 있다. 이를 Elasticsearch에서는 **Mapping**이라고 부른다.

아래 명령어로 users 인덱스에 매핑을 정의해보자.

```plaintext
PUT /users/_mapping 
{	
	"properties": 
    	{ 
    		"name": { "type": "keyword" }, 
        	"age": { "type": "integer" }, 
        	"is_active": { "type": "boolean" } 
    	} 
}
```

![](https://blog.kakaocdn.net/dna/5nM0w/dJMcad1Z8Qx/AAAAAAAAAAAAAAAAAAAAAKbo8GNVJ6uI4C-lXWje6krZ7O0PLWJlRYKNnCdjOLvn/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=R7fNYfScMb%2FtCey96b2N8ALbnmQ%3D align="left")

여기서 핵심은 다음과 같다.

* properties 안에서 field들을 정의한다.
    
* 각 field는 type을 가진다.
    
* **keyword**는 MySQL에서 VARCHAR(문자열) 같은 느낌이라고 생각하면 된다.
    
* integer, boolean도 그대로 이해하면 된다.
    

👉 즉, Mapping은 MySQL에서 schema를 정의하는 과정과 거의 유사하다.

매핑이 잘 정의되었는지 확인하고 싶다면 조회 명령어로 확인할 수 있다.

![](https://blog.kakaocdn.net/dna/kGR7t/dJMcaflgzBZ/AAAAAAAAAAAAAAAAAAAAAPf-eA7H6VJ6DSD_O7FC_IMINX7aM-60Y8nTeeC1T1Y3/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=IgOL5BrozG691ymnS%2FXaKxSqAW0%3D align="left")

\- GET /users

---

#### \- Document 삽입하기 

이제 **실제 데이터를 넣어보자!**

MySQL에서 테이블에 record(row)를 삽입하는 과정과 동일하게, Elasticsearch에서는 index에 **document**를 삽입한다.

```plaintext
POST /users/_doc 
{
    "name": "Bo", 
    "age": 26, 
    "is_active": true 
}
```

![](https://blog.kakaocdn.net/dna/E14Nj/dJMcahwDsZ9/AAAAAAAAAAAAAAAAAAAAADbeqY_7z3icSL1XvYhLDEe_dKg9le5Thrnfh-Eh1OIf/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=%2BdFeswmZ4L6PNcZ8FJrEk%2BUEyyY%3D align="left")

이렇게 하면 Elasticsearch가 **자동으로 랜덤한 \_id 값을 생성해서** document를 저장한다.

---

#### \- Document 조회하기 

삽입된 document를 조회하려면 아래 명령어를 사용한다.

```plaintext
GET /users/_search
```

![](https://blog.kakaocdn.net/dna/da18LM/dJMcag5yKt6/AAAAAAAAAAAAAAAAAAAAAA5ZBzr6gCtUO3lZXblyHwBZ6ZN5hu6dE54miV6V0Sdp/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=29%2BnJL2dIlxo0s%2BKSOKaQfwtzoA%3D align="left")

결과를 확인해보면 hits 안에 document가 들어가 있을 것이고,  
각 document마다 Elasticsearch가 자동으로 생성한 랜덤 \_id 값이 붙어있는 것도 확인할 수 있다.

---

#### \- ID를 지정해서 Document 삽입하기

document를 저장할 때 자동 ID가 아니라, 내가 직접 ID를 지정해서 저장하는 것도 가능하다.

```plaintext
POST /users/_create/1
{
    "name": "Boo", 
    "age": 27, 
    "is_active": true 
}
```

![](https://blog.kakaocdn.net/dna/cOtKA6/dJMcafyOZp0/AAAAAAAAAAAAAAAAAAAAAKTfBrBD40Q3ITBXpCPn5PZibPwkMXFCd0h8ZKy8-gX5/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=AMKf5HpFCTQRQ5%2F%2BFMKXbd2dO1k%3D align="left")

이렇게 하면 **\_id = 1로 document가 저장된다.**

여기서 중요한 포인트는,

👉 \_create 방식은 **같은 ID가 이미 존재하면 저장이 실패한다는 점이다.**  
즉, 중복 저장이 불가능하다. <s>고유 id를 알아서 처리하는..</s>

![](https://blog.kakaocdn.net/dna/bof7mL/dJMcachMz50/AAAAAAAAAAAAAAAAAAAAALQxXHAowAIzvdkm7sI3PoB3KXG3raDu1n4wDfZTUMEY/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=en0TL0wRh0h5t3%2BamAny156QdZk%3D align="left")

---

#### \- 특정 ID로 Document 조회하기

특정 document 하나만 조회하고 싶다면 아래처럼 조회할 수 있다. 

```plaintext
GET /users/_doc/2
```

![](https://blog.kakaocdn.net/dna/K4tQv/dJMcai95osJ/AAAAAAAAAAAAAAAAAAAAABH7P6wP8YLw52XKg4mi_Hv5Jj7VZrEG48j_UrA3GWX_/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=DPWva6%2Fkmf07%2BhiG4v2HF39dFHY%3D align="left")

👉 여기서 마지막 숫자 2는 document의 **"id"** 값이다.

---

#### \- 같은 ID여도 덮어씌우기(업데이트) 하고 싶다면?

위에서 확인한 것처럼 이미 존재하는 id값을 POST 하는 경우 ERROR가 발생했지만, MySQL에서 upsert처럼 동작하게 하려면  아래처럼 PUT을 사용하면 된다. 이미 존재하는 id=1 document에 새로운 값을 가지는 데이터를 PUT 하는 경우

```plaintext
PUT /users/_doc/1 
{ 
    "name": "Boo", 
    "age": 28, 
    "is_active": true 
}
```

![](https://blog.kakaocdn.net/dna/cwPyW7/dJMcabwn5ct/AAAAAAAAAAAAAAAAAAAAACSH-27A60u66nE_67_FHRbnybeohVe6cjnkysYl0CHT/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=J7jfRhYD4N3zc54OWHrVkOFGwj8%3D align="left")

데이터 삽입이 성공하는 모습을 확인할 수 있고,  이후 다시 조회해보면 기존 document가 덮어씌워진 것을 확인할 수 있다.

![](https://blog.kakaocdn.net/dna/4pP9D/dJMcaaxvijr/AAAAAAAAAAAAAAAAAAAAAKdKy9gkyumXX9pYrWesOidJZ9IcXXzKD2vgEix5sMpG/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=uNoNns5cAuzixPDX0E6uI41dZig%3D align="left")

---

#### \- Document 수정하기 (Update)

사실 위에서 사용했던 PUT /users/\_doc/1 자체가  
👉 특정 ID document를 **수정하는 방식**이라고 생각해도된다. <s>같은 의미지 사실상.</s>

즉, Elasticsearch에서는 PUT 요청이

* 없으면 생성
    
* 있으면 덮어쓰기(update)
    

방식으로 동작한다.

---

#### \- 특정 필드만 수정하기

특정 인물의 나이만 변경해야 하는 경우라면?  모든 필드가 아니라, 특정 필드만 수정하고 싶을 수도 있다. 

이 경우에는 \_update를 사용한다.

```plaintext
POST /users/_update/1 
{ 
    "doc": { "age": 29 } 
}
```

![](https://blog.kakaocdn.net/dna/ODBxF/dJMb996qzWL/AAAAAAAAAAAAAAAAAAAAAIfmIkI0XDhCczMfQMnna78I_3zCeTDn5yjtZFH6tn5l/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=WC5dN7zyHj1pOOLFCkgQaBIdW6I%3D align="left")

👉 doc 안에 수정할 필드만 넣어주면 된다.

이 방식은 MySQL의 UPDATE users SET age=29 WHERE id=1 같은 느낌이다.

---

#### \- Document 삭제하기 (Delete)

마지막으로 특정 ID document를 삭제해보자.

```plaintext
DELETE /users/_doc/1
```

![](https://blog.kakaocdn.net/dna/be3FbK/dJMcajuoWhK/AAAAAAAAAAAAAAAAAAAAANeDKQkd6WFTrg4nqhkeuiGqB22wN-5RdlyWHtc7QFHQ/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=NB15eG1PBCUzbzBrTBhbdgz6z8c%3D align="left")

이후 index에서 해당 id의 document를 조회해보면 document가 삭제된 것을 확인할 수 있다.

![](https://blog.kakaocdn.net/dna/bM2nhY/dJMcacvkI9I/AAAAAAAAAAAAAAAAAAAAANW-UWQMViwAULeKGlOSpgpcKjYuhPErrPxa0UuHhSvj/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1772290799&allow_ip=&allow_referer=&signature=SasMSJT00OkGkDEGyZsJekSViAI%3D align="left")

---

## ▶ 마무리

이번 글에서는 Elasticsearch에서 가장 기본이 되는 용어와 CRUD 명령어를 정리해 봤다. 정리해보면 Elasticsearch는 처음엔 생소했지만, 동작 방식 자체는 MySQL과 굉장히 유사하다는 것을 알 수 있었다. 자주 사용하는 코드들을 자주 쳐보면서 채화시키는 것이 중요할 것 같다.

* 인덱스를 만들고
    
* document를 삽입하고
    
* 검색하고
    
* 수정하고
    
* 삭제한다
    

이 흐름만 익히면 막막했던 Elasticsearch와 조금 친해지는 느낌이 든다. 👍👍👍
