Search API는 구조화된 데이터가 포함된 문서를 색인화하는 모델을 제공합니다. 색인을 검색하고 검색결과를 정렬하여 나타낼 수 있습니다. 이 API는 문자열 필드에 대한 전체 텍스트 일치를 지원합니다. 문서와 색인은 검색 작업에 최적화된 별도의 영구 스토리지에 저장됩니다. Search API로 색인화할 수 있는 문서 수에는 제한이 없습니다. 매우 큰 결과 집합을 검색해야 하는 애플리케이션에는 App Engine Datastore가 더 적합할 수 있습니다. search
패키지의 콘텐츠를 보려면 search
패키지 참조를 확인하세요.
개요
Search API는 문서, 색인, 쿼리, 결과라는 네 가지 기본 개념을 기반으로 합니다.
문서
문서란 사용자 데이터가 포함된 필드 목록과 고유한 ID가 있는 객체를 말합니다. 각 필드에는 이름과 유형이 있습니다. 필드에는 포함된 값의 종류에 따라 구분되는 다음과 같은 여러 유형이 있습니다.
- Atom 필드 - 분할할 수 없는 문자열
- 텍스트 필드 - 단어 단위로 검색할 수 있는 일반 텍스트 문자열
- HTML 필드 - HTML 마크업 태그를 포함하는 문자열. 마크업 태그 외부의 텍스트만 검색 가능
- 숫자 필드 - 부동 소수점 숫자
- 시간 필드 - 밀리초 단위로 저장되는
time.Time
값 - 지리 좌표 필드 - 위도와 경도 좌표가 있는 데이터 객체
문서 하나의 최대 크기는 1MB입니다.
색인
색인은 검색을 위해 문서를 저장합니다. 단일 문서는 ID로, 문서 범위는 연속된 ID로 검색할 수 있으며 색인의 모든 문서를 검색할 수도 있습니다. 또한 색인을 검색하여 쿼리 문자열로 지정된 필드와 필드 값에 대한 특정 기준을 충족하는 문서를 가져올 수 있습니다. 또한 여러 문서를 서로 다른 색인에 추가하여 그룹으로 관리할 수 있습니다.
색인에 추가할 수 있는 문서 수 또는 사용할 수 있는 색인 수에는 제한이 없습니다. 색인 하나에 포함된 모든 문서의 전체 크기는 기본적으로 10GB로 제한됩니다. App Engine 관리자 역할이 있는 사용자는 Google Cloud 콘솔 App Engine Search 페이지에서 요청을 제출하여 크기를 최대 200GB까지 늘릴 수 있습니다.
쿼리
색인을 검색하려면 쿼리 문자열과 몇 가지 추가 옵션으로 이루어진 쿼리를 구성해야 합니다. 쿼리 문자열은 하나 이상의 문서 필드 값에 대한 조건을 지정합니다. 색인을 검색하면 색인의 문서 중 해당 필드가 쿼리를 충족하는 문서만 반환됩니다.
가장 간단한 쿼리는 필드 값만 들어있는 문자열입니다. 이러한 쿼리를 '전체 검색'이라고도 합니다. 다음 검색에서는 'rose'와 'water'라는 단어가 포함된 문서를 검색하는 문자열을 사용합니다.
다음은 날짜 필드에 날짜 1776년 7월 4일 또는 텍스트 필드에 문자열 '1776-07-04'가 포함된 문서를 검색합니다.
쿼리 문자열을 더욱 구체적으로 구성할 수 있습니다. 필드 및 필드 값에 대한 제약조건을 지정하는 하나 이상의 항을 포함할 수 있습니다. 항의 정확한 형식은 필드 유형에 따라 다릅니다. 예를 들어 'product'라는 텍스트 필드와 'price'라는 숫자 필드가 있는 경우 두 항을 포함하는 쿼리 문자열은 다음과 같습니다.
쿼리 옵션은 이름에서 알 수 있듯이 필수 항목은 아니며, 다음과 같이 다양한 기능을 제공합니다.
- 검색결과에 반환되는 문서 수를 제어합니다.
- 결과에 포함할 문서 필드를 지정합니다. 기본 동작은 원본 문서의 모든 필드를 포함하는 것입니다. 필드 중 일부만 결과에 포함되도록 지정할 수 있으며, 원본 문서에는 영향이 없습니다.
- 결과를 정렬합니다.
FieldExpressions
를 사용하여 문서에 '계산 필드'를 만들고 스니펫을 사용하여 요약 텍스트 필드를 만듭니다.- 오프셋과 커서를 사용하여 각 쿼리에서 일치하는 문서 중 일부만 반환함으로써 검색결과에 대한 페이징을 지원합니다.
실행된 쿼리 레코드를 보관하려면 애플리케이션에서 쿼리 문자열을 로깅하는 것이 좋습니다.
검색결과
Search
호출은 일치하는 전체 문서 집합을 반환하기 위해 사용될 수 있는 Iterator
값을 반환합니다.
추가 교육 자료
이 문서 외에도 Google 개발자 아카데미에서 Search API에 관한 2부작 교육 강의를 참조할 수 있습니다. (이 강의에서는 Python API를 사용하지만, 검색이라는 개념에 대한 추가 내용이 도움이 될 수 있습니다.)
문서 및 필드
문서는 필드의 목록을 구성하는 여러 개의 Go struct로 표현됩니다. 또한FieldLoadSaver
인터페이스를 구현하는 모든 유형으로 표현될 수 있습니다.
문서 식별자
색인에 포함된 모든 문서에는 고유한 문서 식별자, 즉 docID
가 있어야 합니다.
식별자를 사용하면 검색을 수행하지 않고 색인에서 문서를 가져올 수 있습니다. 기본적으로 Search API는 문서를 만들 때 자동으로 docID
를 생성합니다. 또한 문서를 만들 때 docID
를 직접 지정할 수 있습니다. docID
는 육안 확인 및 인쇄가 가능한 ASCII 문자(ASCII 코드 33~126, 경계 포함)로만 구성되어야 하며 500자를 초과할 수 없습니다. 또한 맨 앞에 느낌표('!')가 올 수 없으며 맨 앞이나 맨 뒤에 연속된 2개의 밑줄('__')이 올 수 없습니다.
읽기 쉽고 의미 있는 고유한 문서 식별자를 만드는 것이 편리하긴 하지만 docID
를 검색에 포함할 수는 없습니다. 예를 들어 색인에 포함된 문서가 부품을 나타내며 부품의 일련번호를 docID
로 사용한다고 가정해 보겠습니다. 이 경우 단일 부품에 대한 문서는 매우 효율적으로 검색할 수 있지만, 구매 날짜 등의 다른 필드 값과 함께 특정 범위의 일련번호를 검색할 수 없게 됩니다. 일련번호를 Atom 필드에 저장하면 이러한 문제가 없습니다.
문서 필드
문서는 이름, 유형, 해당 유형의 단일 값을 갖는 필드를 포함합니다. 유형이 서로 다른 두 개 이상의 필드가 동일한 이름을 가질 수도 있습니다. 예를 들어 'age'라는 이름으로 두 필드를 정의하면서 한 필드에는 텍스트 유형(값: 'twenty-two')을, 다른 한 필드에는 숫자 유형(값: 22)을 사용할 수 있습니다.
필드 이름
필드 이름은 대소문자를 구분하며 ASCII 문자만 포함할 수 있습니다. 문자로 시작해야 하며 문자, 숫자, 밑줄로 구성될 수 있습니다. 필드 이름은 500자를 초과할 수 없습니다.
다중 값 필드
필드는 필드 유형과 일치하는 하나의 값만 포함할 수 있습니다. 고유한 필드 이름을 사용할 필요는 없습니다. 문서는 이름과 유형이 같은 여러 필드를 가질 수 있으며, 이 방법으로 다중 값 필드를 나타낼 수 있습니다. 그러나 동일한 이름을 가진 날짜 필드와 숫자 필드를 반복할 수는 없습니다. 문서에 이름이 같지만 유형은 다른 여러 필드가 포함될 수도 있습니다.
필드 유형
문자열을 저장하는 필드에는 세 가지 종류가 있으며, 이러한 필드를 문자열 필드라고 통칭합니다.
- 텍스트 필드: 최대 길이가 1024**2자인 문자열입니다.
- HTML 필드: 최대 길이가 1024**2자인 HTML 형식의 문자열입니다.
- Atom 필드: 최대 길이가 500자인 문자열입니다.
또한 텍스트가 아닌 데이터를 저장하는 세 가지 필드 유형이 있습니다.
- 숫자 필드: -2,147,483,647에서 2,147,483,647 사이의 배정밀도 부동 소수점 값입니다.
- 시간 필드 - 밀리초 단위로 저장되는
time.Time
값 - 지리 좌표 필드: 위도와 경도 좌표로 표현되는 지구상의 한 지점
문자열 필드 유형은 Go에서 기본 제공하는 string
유형과 search
패키지의 HTML
및 Atom
유형입니다. 숫자 필드는 Go에서 기본 제공하는 float64
유형으로 표현되며, 시간 필드는 time.Time
유형을 사용하고, 지리 좌표 필드는 appengine
패키지의 GeoPoint
유형을 사용합니다.
문자열 및 시간 필드의 특수 처리
시간, 텍스트, HTML 필드가 있는 문서가 색인에 추가되면 몇 가지 특수 처리가 실행됩니다. 시스템이 내부적으로 어떻게 작동하는지 이해하면 Search API를 효과적으로 사용하는 데 도움이 됩니다.
문자열 필드 토큰화
HTML 또는 텍스트 필드를 색인화하면 필드의 내용이 토큰화됩니다. 즉, 문자열이 공백 또는 특수문자(문장부호, 해시 기호, 백슬래시 등)가 나타나는 모든 위치를 기준으로 여러 토큰으로 분할됩니다. 색인에는 각 토큰에 대한 항목이 포함됩니다. 이렇게 하면 필드 값의 일부만으로 구성된 키워드와 구문을 검색할 수 있습니다. 예를 들어 'dark'를 검색하면 'it was a dark and stormy night' 문자열이 포함된 텍스트 필드가 있는 문서가 검색되고, 'time'을 검색하면 'this is a real-time system' 문자열이 포함된 텍스트 필드가 있는 문서가 검색됩니다.
HTML 필드에서 마크업 태그로 묶인 텍스트는 토큰화되지 않으므로 it was a <strong>dark</strong> night
를 포함하는 HTML 필드가 있는 문서는 'night'로는 검색되지만 'strong'으로는 검색되지 않습니다. 마크업 텍스트를 검색하려면 텍스트 필드에 저장해야 합니다.
Atom 필드는 토큰화되지 않습니다. 값이 'bad weather'인 Atom 필드가 있는 문서는 전체 문자열 'bad weather'로만 검색됩니다. 'bad' 또는 'weather' 단독으로는 검색되지 않습니다.
토큰화 규칙
밑줄(_)과 앰퍼샌드(&) 문자는 단어를 토큰으로 나누지 않습니다.
공백, 캐리지 리턴, 라인 피드, 가로 탭, 세로 탭, 폼 피드, NULL과 같은 공백 문자는 항상 단어를 토큰으로 나눕니다.
다음 문자는 문장부호로 취급되며 단어를 토큰으로 나눕니다.
! " % ( ) * , - | / [ ] ] ^ ` : = > ? @ { } ~ $ 다음 표에 나온 문자는 일반적으로 단어를 토큰으로 나누지만 어떠한 상황에서 나타났는지에 따라 다르게 처리될 수 있습니다.
문자 규칙 <
HTML 필드에서 '미만' 기호는 HTML 태그의 시작을 나타내며 무시됩니다. +
하나 이상의 '더하기' 기호로 이루어진 문자열은 C++와 같이 단어 끝에 사용될 경우 단어의 일부로 취급됩니다. #
'해시' 기호는 a, b, c, d, e, f, g, j, x가 앞에 올 경우 단어의 일부로 취급됩니다. a# ~ g#은 음표, j#과 x#은 프로그래밍 언어, c#은 둘 다에 해당합니다. #google과 같이 단어 앞에 '#'이 올 경우 해시태그로 취급되어 해시가 단어의 일부가 됩니다. '
아포스트로피는 'John's hat'과 같이 문자 's'와 단어 분리 문자가 연달아 뒤에 올 경우 문자로 취급됩니다. .
숫자 사이의 소수점은 소수 구분기호로서 숫자의 일부로 취급됩니다. A.B.C와 같이 약어에 사용된 경우에도 단어의 일부로 취급될 수 있습니다. -
I-B-M과 같이 약어에 사용된 대시는 단어의 일부입니다. 문자와 숫자('A-Z', 'a-z', '0-9')를 제외한 다른 7비트 문자는 모두 문장부호로 취급되며 단어를 토큰으로 나눕니다.
그 외 나머지 경우는 UTF-8 문자로 파싱됩니다.
약어
토큰화에서는 특수한 규칙을 사용하여 'I.B.M', 'a-b-c', 'C I A' 등의 약어를 인식합니다. 약어는 여러 영문자를 한 글자씩 동일한 구분문자로 나눈 문자열입니다. 사용 가능한 구분기호는 마침표, 대시, 임의 개수의 공백입니다. 구분문자는 약어가 토큰화될 때 문자열에서 삭제됩니다. 따라서 위에서 예시로 든 문자열은 'ibm', 'abc', 'cia'로 토큰화됩니다. 원본 텍스트는 문서 필드에 유지됩니다.
약어를 다룰 때 주의할 점은 다음과 같습니다.
- 약어는 21자를 초과할 수 없습니다. 유효하지만 21자를 초과하는 약어 문자열은 각각 21자 이하의 연속된 여러 약어로 분할됩니다.
- 약어의 문자가 공백으로 구분된 경우 대소문자를 혼용할 수 없습니다. 마침표와 대시로 구분된 약어는 대소문자를 혼용할 수 있습니다.
- 약어를 검색할 때는 약어의 표준 형식(구분기호 없는 문자열)을 입력할 수도 있고, 각 문자를 대시 또는 점으로 구분한 약어를 입력할 수도 있지만 대시와 점을 혼용할 수는 없습니다. 따라서 텍스트 'I.B.M'을 검색하려는 경우 'I-B-M', 'I.B.M', 'IBM' 모두 검색어로 사용할 수 있습니다.
시간 필드 정확도
문서에 시간 필드를 만들 때 값을 time.Time
으로 설정합니다.
시간 필드를 색인화하고 검색할 수 있도록 시간 구성요소는 모두 무시되며 날짜는 1970년 1월 1일(UTC) 이후 경과한 일수로 변환됩니다. 즉, 시간 필드에는 정확한 시간 값이 포함될 수 있지만 날짜 쿼리는 yyyy-mm-dd
형식으로만 시간 필드 값을 지정할 수 있습니다. 따라서 여러 시간 필드가 같은 날짜를 포함할 경우 정렬 순서가 명확히 정의되지 않습니다. time.Time
유형은 시간을 나노초 단위로 나타내지만 Search API는 시간을 밀리초 단위로만 저장합니다.
기타 문서 속성
문서의 순위는 검색 시 반환되는 문서의 기본 순서를 결정하는 양의 정수입니다. 기본적으로 순위는 문서 생성 시점에 설정되며 값은 2011년 1월 1일 이후 경과된 초 수입니다. 문서를 만들 때 명시적으로 순위를 설정할 수 있습니다. 여러 문서에 같은 순위를 할당하지 않는 것이 좋습니다. 또한 문서 10,000개 이상에 같은 순위를 부여해서는 안 됩니다.
정렬 옵션을 지정하는 경우 순위를 정렬 키로 사용할 수 있습니다. 순위가 정렬 표현식 또는 필드 표현식에 사용되면 _rank
로 참조됩니다.
순위 설정 방법에 대한 자세한 내용은 DocumentMetadata
참조를 확인하세요.
Field
구조체의 언어 속성은 필드가 인코딩되는 언어를 지정합니다.
문서에서 다른 리소스로 연결
문서의 docID
와 기타 필드를 애플리케이션의 다른 리소스로 연결되는 링크로 사용할 수 있습니다. 예를 들어 Blobstore를 사용하는 경우 docID
또는 Atom 필드 값을 데이터의 BlobKey로 설정하여 문서에 특정 blob을 연결할 수 있습니다.
문서 만들기
다음 코드 샘플에서는 문서 객체를 만드는 방법을 보여줍니다. User
유형은 문서 구조를 지정하고 User
값은 일반적인 방식으로 생성됩니다.
색인 작업
색인에 문서 추가
색인에 문서를 추가하면 문서가 영구 스토리지에 복사되고 각 필드가 이름, 유형, docID
에 따라 색인화됩니다.
다음 코드 예시에서는 색인에 액세스하고 문서를 색인에 추가하는 방법을 보여줍니다.
색인에 문서를 추가할 때 docID
가 동일한 문서가 색인에 이미 있는 경우 새 문서가 기존 문서를 대체합니다. 별도의 경고는 없습니다. 문서를 만들거나 색인에 추가하기 전에 Index.Get
을 호출하면 특정 docID
가 이미 있는지 확인할 수 있습니다.
Put
메서드는 docID
를 반환합니다. docID
를 직접 지정하지 않은 경우 결과를 조사하여 생성된 docID
를 확인할 수 있습니다.
Index
유형의 인스턴스가 생성되었더라도 영구 색인이 실제로 존재한다는 보장은 없습니다. 영구 색인은 put
메서드를 사용하여 문서를 처음 추가하면 만들어집니다.
문서 업데이트
문서를 색인에 추가하고 나면 문서를 변경할 수 없으며 필드 추가, 삭제, 필드 값 변경도 불가능합니다. 그러나 docID
가 같은 새 문서로 기존 문서를 대체할 수는 있습니다.
docID로 문서 검색
Index.Get
메서드를 사용하여 색인에서 docID
로 문서를 검색합니다.
콘텐츠로 문서 검색
색인에서 문서를 검색하려면 쿼리 문자열을 구성하고 Index.Search
를 호출합니다.
Search
는 일치하는 문서를 내림차순으로 생성하는 반복기를 반환합니다.
색인 삭제
각 색인은 색인이 생성된 문서와 색인 스키마로 구성됩니다. 색인을 삭제하려면 색인의 모든 문서를 삭제한 후 색인 스키마를 삭제합니다.
삭제하려는 문서의 docID
를 Index.Delete
메서드에 지정하여 색인에서 문서를 삭제할 수 있습니다.
eventual consistency
색인에 문서를 추가, 업데이트 또는 삭제하면 변경사항이 여러 데이터 센터로 전파됩니다. 일반적으로 전파 속도는 매우 빠르지만 소요 시간은 일정하지 않습니다. Search API는 eventual consistency를 보장합니다. 경우에 따라 하나 이상의 문서를 검색하면 최신 변경사항이 반영되지 않은 결과가 반환될 수 있습니다.
색인 스키마
모든 색인에는 포함된 문서에 나타나는 모든 필드 이름과 필드 유형을 보여주는 스키마가 있습니다. 스키마는 직접 정의할 수 없습니다. 스키마는 문서가 색인에 추가될 때 업데이트되며 동적으로 유지 관리됩니다. 간단한 스키마는 다음과 같이 JSON과 유사한 형식입니다.
{'comment': ['TEXT'], 'date': ['DATE'], 'author': ['TEXT'], 'count': ['NUMBER']}
사전의 각 키는 문서 필드의 이름입니다. 키 값은 해당 필드 이름과 함께 사용된 필드 유형의 목록입니다. 이름은 같고 유형은 서로 다른 여러 필드를 사용한 경우 스키마는 다음과 같이 필드 이름 하나에 두 개 이상의 필드 유형을 나열합니다.
{'ambiguous-integer': ['TEXT', 'NUMBER', 'ATOM']}
스키마에 한 번 표시된 필드는 어떠한 경우에도 삭제할 수 없습니다. 색인에 더 이상 해당 필드 이름을 갖는 문서가 없더라도 필드를 삭제할 수는 없습니다.
스키마는 객체 프로그래밍으로의 '클래스'를 정의하지 않습니다. Search API의 체계에서는 모든 문서가 고유하며 색인은 다양한 유형의 문서를 포함할 수 있습니다. 동일한 필드 목록을 가진 여러 객체의 컬렉션을 클래스의 인스턴스로 간주하려는 경우 코드에서 직접 추상화를 적용해야 합니다. 예를 들어 동일한 필드 집합을 가진 모든 문서를 자체 색인에 보관할 수 있습니다. 색인 스키마는 클래스 정의로, 색인의 각 문서는 클래스의 인스턴스로 볼 수 있습니다.
Google Cloud 콘솔에서 색인 보기
Google Cloud 콘솔에서 애플리케이션의 색인 및 색인에 포함된 문서에 대한 정보를 열람할 수 있습니다. 색인 이름을 클릭하면 색인에 포함된 문서가 표시됩니다. 색인에 정의된 스키마 필드가 모두 표시되고, 해당 이름의 필드를 갖는 각 문서의 필드 값이 표시됩니다. 콘솔에서 색인 데이터에 대한 쿼리를 직접 실행할 수도 있습니다.
Search API 할당량
Search API에는 몇 가지 무료 할당량이 제공됩니다.
리소스 또는 API 호출 | 무료 할당량 |
---|---|
총 저장용량(문서 및 색인) | 0.25GB |
쿼리 | 쿼리 1,000개/일 |
색인에 문서 추가 | 0.01GB/일 |
Search API는 이러한 한도를 적용하여 서비스의 안정성을 보장합니다. 무료 앱과 유료 앱 모두에 한도가 적용됩니다.
리소스 | 안전 할당량 |
---|---|
최대 쿼리 사용량 | 분당 쿼리 실행 누적 시간 100분 |
추가 또는 삭제되는 최대 문서 | 15,000/분 |
색인당 최대 크기(색인 수는 제한 없음) | 10GB |
API 사용량은 호출 유형에 따라 다양한 방식으로 계산됩니다.
Index.Search
: 각 API 호출은 쿼리 1회로 계산됩니다. 실행 시간은 호출 지연 시간과 동일합니다.Index.Put
: 색인에 문서를 추가할 때 각 문서의 크기와 문서 수가 색인이 생성된 할당량에 합산됩니다.- 다른 모든 Search API 호출은 관련 작업 수를 기준으로 계산됩니다.
Index.Get
: 각 문서가 실제로 반환될 때마다 또는 아무것도 반환되지 않은 경우 작업 1회로 계산됩니다.Index.Delete
: 요청에 포함된 문서 1개당 또는 요청이 비어 있는 경우 작업 1회로 계산됩니다.
쿼리 처리량에 할당량이 적용되는 이유는 사용자 한 명이 검색 서비스를 독점하지 못하도록 하기 위함입니다. 여러 쿼리가 동시에 실행될 수 있으므로 각 애플리케이션은 클럭 시간 1분당 실행 시간을 최대 100분까지 소비하는 쿼리를 실행할 수 있습니다. 짧은 쿼리를 여러 개 실행하면 이 한도에 도달할 가능성이 거의 없습니다. 할당량을 초과하면 할당량이 복원되는 다음 타임 슬라이스까지 후속 쿼리가 실패합니다. 할당량은 1분 단위로 엄격하게 적용되지 않으며, 변형된 leaky bucket 알고리즘을 사용하여 5초 단위로 검색 대역폭을 제어합니다.
할당량에 대한 자세한 내용은 할당량 페이지를 참조하세요. 앱에서 이러한 할당량을 초과하려고 하면 할당량 부족 오류가 반환됩니다.
이러한 한도는 분당으로 적용되지만 콘솔에서는 각 항목의 일일 총계가 표시됩니다. 실버, 골드, 플래티넘 지원을 신청한 고객은 지원팀 담당자에게 처리량 한도 상향을 요청할 수 있습니다.
Search API 가격 책정
무료 할당량을 넘어선 사용량에는 다음과 같이 청구가 적용됩니다.
리소스 | 비용 |
---|---|
총 저장용량(문서 및 색인) | GB당 $0.18/월 |
쿼리 | 쿼리 10,000개당 $0.50 |
검색 가능한 문서의 색인 생성 | GB당 $2.00 |
가격 책정에 대한 추가 정보는 가격 책정 페이지를 참조하세요.