색인 및 검색 기초
원본 보기색인 및 검색 기초
이 빠른 시작 가이드는 Elasticsearch의 핵심 개념인 인덱스, 문서, 필드 타입 매핑을 직접 실습하며 소개합니다. 인덱스를 생성하고, 문서를 추가하고, 동적 매핑과 명시적 매핑을 다루고, 첫 기본 검색을 수행하는 방법을 배웁니다.
코드 예제는 기본적으로 Console 문법으로 작성되어 있습니다. Console UI에서 다른 프로그래밍 언어로 변환할 수 있습니다.
이 가이드는 어떤 Elasticsearch 배포 환경에서도 따라 할 수 있습니다. 모든 배포 옵션을 보려면 Deploy > Choosing your deployment type를 참고하세요. 빠르게 시작하려면 Docker에서 로컬로 클러스터를 띄우세요.
이 빠른 시작 가이드는 Elasticsearch API를 사용하지만, Elasticsearch에 데이터를 추가하는 방법은 이 외에도 많습니다.
데이터는 문서(document)라고 부르는 JSON 객체 형태로 Elasticsearch에 추가합니다. Elasticsearch는 이러한 문서를 검색 가능한 인덱스에 저장합니다.
-
인덱스 생성
books라는 이름의 새 인덱스를 생성합니다:PUT /books다음 응답은 인덱스가 성공적으로 생성되었음을 나타냅니다.
응답 예시{ "acknowledged": true, "shards_acknowledged": true, "index": "books" } -
단일 문서 추가
다음 요청으로
books인덱스에 문서 하나를 추가합니다. 인덱스가 아직 존재하지 않으면 이 요청이 자동으로 인덱스를 생성합니다.POST books/_doc{ "name": "Snow Crash", "author": "Neal Stephenson", "release_date": "1992-06-01", "page_count": 470 }응답에는 Elasticsearch가 문서에 대해 생성한 메타데이터가 포함되며, 여기에는 인덱스 내에서 해당 문서의 고유한
_id도 들어 있습니다.응답 예시{ "_index": "books", "_id": "O0lG2IsBaSa7VYx_rEia", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }_index: 문서가 추가된 인덱스입니다._id: 문서의 고유 식별자입니다._version: 문서의 버전입니다.result: 인덱싱 작업의 결과입니다._shards: 인덱싱 작업이 실행된 샤드 수와 성공한 샤드 수에 대한 정보입니다.total: 인덱스의 전체 샤드 수입니다.successful: 인덱싱 작업이 수행된 샤드 수입니다.failed: 인덱싱 작업 중 실패한 샤드 수입니다. 0은 실패가 없음을 의미합니다._seq_no: 샤드에서 인덱싱 작업이 일어날 때마다 단조 증가하는 숫자입니다._primary_term: 주 샤드가 다른 노드에 할당될 때마다 단조 증가하는 숫자입니다.
-
여러 문서 추가
_bulk엔드포인트를 사용하면 한 번의 요청으로 여러 문서를 추가할 수 있습니다. 벌크 데이터는 줄바꿈으로 구분된 JSON(NDJSON) 형식이어야 합니다.POST /_bulk{ "index" : { "_index" : "books" } } {"name": "Revelation Space", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585} { "index" : { "_index" : "books" } } {"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328} { "index" : { "_index" : "books" } } {"name": "Fahrenheit 451", "author": "Ray Bradbury", "release_date": "1953-10-15", "page_count": 227} { "index" : { "_index" : "books" } } {"name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268} { "index" : { "_index" : "books" } } {"name": "The Handmaids Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311}오류가 없음을 나타내는 응답을 받게 됩니다.
응답 예시{ "errors": false, "took": 29, "items": [ { "index": { "_index": "books", "_id": "QklI2IsBaSa7VYx_Qkh-", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 1, "_primary_term": 1, "status": 201 } }, { "index": { "_index": "books", "_id": "Q0lI2IsBaSa7VYx_Qkh-", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 2, "_primary_term": 1, "status": 201 } }, { "index": { "_index": "books", "_id": "RElI2IsBaSa7VYx_Qkh-", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 3, "_primary_term": 1, "status": 201 } }, { "index": { "_index": "books", "_id": "RUlI2IsBaSa7VYx_Qkh-", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 4, "_primary_term": 1, "status": 201 } }, { "index": { "_index": "books", "_id": "RklI2IsBaSa7VYx_Qkh-", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 5, "_primary_term": 1, "status": 201 } } ] } -
동적 매핑 사용
매핑은 관계형 데이터베이스의 스키마처럼 Elasticsearch에서 데이터가 저장되고 색인되는 방식을 정의합니다.
동적 매핑을 사용하면 Elasticsearch가 새 필드에 대한 매핑을 자동으로 생성합니다. 지금까지 추가한 문서들은 인덱스를 생성할 때 매핑을 지정하지 않았기 때문에 동적 매핑을 사용했습니다.
동적 매핑이 어떻게 동작하는지 확인하려면, 기존 문서에 없는 필드를 포함한 새 문서를
books인덱스에 추가해 보세요.POST /books/_doc{ "name": "The Great Gatsby", "author": "F. Scott Fitzgerald", "release_date": "1925-04-10", "page_count": 180, "language": "EN" }- 새로 추가된 필드입니다.
get mapping API로
books인덱스의 매핑을 확인하세요. 새 필드language가text데이터 타입으로 매핑에 추가된 것을 볼 수 있습니다.GET /books/_mapping다음 응답은 Elasticsearch가 생성한 매핑을 보여줍니다.
응답 예시{ "books": { "mappings": { "properties": { "author": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "language": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "page_count": { "type": "long" }, "release_date": { "type": "date" } } } } } -
명시적 매핑 정의
my-explicit-mappings-books라는 인덱스를 생성하고 매핑을 직접 지정합니다. 각 필드의 속성을 JSON 객체로 전달하세요. 이 객체에는 필드 데이터 타입과 추가적인 매핑 파라미터가 포함되어야 합니다.PUT /my-explicit-mappings-books{ "mappings": { "dynamic": false, "properties": { "name": { "type": "text" }, "author": { "type": "text" }, "release_date": { "type": "date", "format": "yyyy-MM-dd" }, "page_count": { "type": "integer" } } } }dynamic: 인덱스의 동적 매핑을 끕니다. 매핑에 정의하지 않은 필드도 문서의_source필드에는 저장되지만, 색인하거나 검색할 수는 없습니다.properties: 필드와 그에 해당하는 데이터 타입을 정의합니다.
다음 응답은 작업이 성공했음을 나타냅니다.
응답 예시{ "acknowledged": true, "shards_acknowledged": true, "index": "my-explicit-mappings-books" }명시적 매핑은 인덱스를 생성할 때 정의되며, 문서는 이 매핑을 따라야 합니다. update mapping API를 사용할 수도 있습니다. 인덱스의
dynamic플래그가true로 설정되어 있으면 매핑을 수정하지 않고도 문서에 새 필드를 추가할 수 있어, 명시적 매핑과 동적 매핑을 함께 사용할 수 있습니다. 매핑 관리 및 업데이트에 대해 자세히 알아보세요.
색인된 문서는 _search API를 통해 거의 실시간으로 검색할 수 있습니다.
-
모든 문서 검색
다음 요청으로
books인덱스의 모든 문서를 검색합니다:GET books/_search응답 예시{ "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 7, "relation": "eq" }, "max_score": 1, "hits": [ { "_index": "books", "_id": "CwICQpIBO6vvGGiC_3Ls", "_score": 1, "_source": { "name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268 } }, ... (truncated) ] } }took: Elasticsearch가 검색을 실행하는 데 걸린 시간(밀리초)timed_out: 검색이 타임아웃되었는지 여부_shards: 검색이 수행된 샤드 수와 성공한 샤드 수에 대한 정보hits: 검색 결과를 담고 있음total: 일치하는 전체 문서 수에 대한 정보max_score: 일치하는 모든 문서 중 가장 높은 관련성 점수_index: 문서가 속한 인덱스_id: 문서의 고유 식별자_score: 문서의 관련성 점수_source: 색인 시 전달된 원본 JSON 객체
-
match 쿼리로 검색
match쿼리를 사용하면 특정 필드에 특정 값이 포함된 문서를 검색할 수 있습니다. 전문 검색에 사용하는 표준 쿼리입니다.다음 요청으로
books인덱스에서name필드에brave가 포함된 문서를 검색합니다:GET books/_search{ "query": { "match": { "name": "brave" } } }Tip이 예제는 Elasticsearch의 기본 쿼리 언어인 Query DSL을 사용합니다.
응답 예시{ "took": 9, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.6931471, "hits": [ { "_index": "books", "_id": "CwICQpIBO6vvGGiC_3Ls", "_score": 0.6931471, "_source": { "name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268 } } ] } }max_score: 결과에서 가장 높은 점수를 받은 문서의 점수입니다. 이 경우 일치하는 문서가 하나뿐이므로max_score는 그 문서의 점수입니다.
언제든 처음부터 다시 시작하기 위해 인덱스를 삭제하려면 delete index API를 사용하세요.
예를 들어, 다음 요청으로 이 빠른 시작 가이드에서 생성한 인덱스를 삭제할 수 있습니다:
DELETE /books
DELETE /my-explicit-mappings-books
인덱스를 삭제하면 해당 인덱스의 문서, 샤드, 메타데이터가 영구적으로 삭제됩니다.
이 빠른 시작 가이드에서는 Elasticsearch로 인덱스를 생성하고, 데이터를 추가하고, 기본 검색을 수행하는 기초를 다뤘습니다. Elasticsearch Python 클라이언트로 비슷한 단계를 실습해 보려면 Build your first search query with Python으로 이동하세요. 다음 자료는 Elasticsearch 개념을 더 깊이 이해하고 데이터 검색용 쿼리 언어의 기초를 익히는 데 도움이 됩니다: