분석 API
분석 API (Analyze API)
1.0 버전에서 도입되었어요. Analyze API는 텍스트 분석을 수행하게 해줘요. 텍스트 분석은 구조화되지 않은 텍스트를 검색에 최적화된 개별 토큰(보통 단어)으로 변환하는 과정이에요. 문자 필터, 토크나이저, 토큰 필터, 노멀라이저 같은 일반적인 분석 구성 요소에 대한 자세한 내용은 Analyzers 문서를 참고하세요.
Analyze API는 텍스트 문자열을 분석해 결과 토큰을 반환해요.
Security 플러그인을 사용한다면 manage index 권한이 있어야 해요. 텍스트만 분석하려면 manage cluster 권한이 있어야 해요.
출처: 문서
본문
엔드포인트 (Endpoints)
GET /_analyze
GET /{index}/_analyze
POST /_analyze
POST /{index}/_analyze
GET과 POST 두 방식 모두로 analyze 요청을 보낼 수 있지만, 둘 사이에는 중요한 차이가 있어요. GET 요청은 데이터가 인덱스에 캐시되어 다음에 요청할 때 더 빨리 검색되게 해요. POST 요청은 아직 존재하지 않는 문자열을 분석기에 보내 인덱스에 이미 있는 데이터와 비교하게 해요. POST 요청은 캐시되지 않아요.
경로 파라미터 (Path parameter)
요청에 다음 선택적 경로 파라미터를 포함할 수 있어요.
| 파라미터 | 데이터 타입 | 설명 |
|---|---|---|
index |
String | 분석기를 도출하는 데 사용하는 인덱스. |
요청 본문 필드 (Request body fields)
아래 표는 사용 가능한 요청 본문 필드를 정리한 거예요.
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
text |
String 또는 String 배열 | 분석할 텍스트. 문자열 배열을 제공하면 텍스트가 다중 값 필드로 분석돼요. 필수. |
analyzer |
String | 텍스트 필드에 적용할 분석기의 이름. 분석기는 인덱스에 내장(built-in)되거나 설정(config)될 수 있어요. analyzer를 지정하지 않으면 Analyze API는 field 필드의 매핑에 정의된 분석기를 사용해요. field 필드를 지정하지 않으면 Analyze API는 인덱스의 기본 분석기를 사용해요. 인덱스를 지정하지 않았거나 인덱스에 기본 분석기가 없으면 Analyze API는 standard 분석기를 사용해요. 선택 사항. Analyzers 참고. |
attributes |
String 배열 | explain 필드의 출력을 필터링하기 위한 토큰 속성 배열. |
char_filter |
String 배열 | tokenizer 필드 이전에 문자를 전처리하기 위한 문자 필터 배열. 선택 사항. Character filters 참고. |
explain |
Boolean | true면 응답에 토큰 속성과 추가 세부 정보를 포함해요. 선택 사항. 기본값은 false예요. |
field |
String | 분석기를 도출하기 위한 필드. field를 지정하면 index 경로 파라미터도 함께 지정해야 해요. analyzer 필드를 지정하면 field의 값을 덮어써요. field를 지정하지 않으면 Analyze API는 인덱스의 기본 분석기를 사용해요. index 필드를 지정하지 않았거나 인덱스에 기본 분석기가 없으면 Analyze API는 standard 분석기를 사용해요. 선택 사항. |
filter |
String 배열 | tokenizer 필드 이후에 적용할 토큰 필터 배열. 선택 사항. Token filters 참고. |
normalizer |
String | 텍스트를 단일 토큰으로 변환하는 노멀라이저. 선택 사항. Normalizers 참고. |
tokenizer |
String | text 필드를 토큰으로 변환하는 토크나이저. 선택 사항. Tokenizers 참고. |
텍스트 문자열 배열 분석
text 필드에 문자열 배열을 전달하면 다중 값 필드로 분석돼요.
GET /_analyze
{
"analyzer": "standard",
"text": [
"first array element",
"second array element"
]
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "first",
"start_offset" : 0,
"end_offset" : 5,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "array",
"start_offset" : 6,
"end_offset" : 11,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "element",
"start_offset" : 12,
"end_offset" : 19,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "second",
"start_offset" : 20,
"end_offset" : 26,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "array",
"start_offset" : 27,
"end_offset" : 32,
"type" : "<ALPHANUM>",
"position" : 4
},
{
"token" : "element",
"start_offset" : 33,
"end_offset" : 40,
"type" : "<ALPHANUM>",
"position" : 5
}
]
}
내장 분석기 적용 (Apply a built-in analyzer)
index 경로 파라미터를 생략하면 내장 분석기 중 아무거나 텍스트 문자열에 적용할 수 있어요. 다음 요청은 standard 내장 분석기로 텍스트를 분석해요:
GET /_analyze
{
"analyzer": "standard",
"text": "OpenSearch text analysis"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "opensearch",
"start_offset" : 0,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "text",
"start_offset" : 11,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "analysis",
"start_offset" : 16,
"end_offset" : 24,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
커스텀 분석기 적용 (Apply a custom analyzer)
자신만의 분석기를 만들어 analyze 요청에서 지정할 수 있어요. 이 시나리오에서는 books2 인덱스와 연결된 lowercase_ascii_folding이라는 커스텀 분석기가 생성되어 있어요. 이 분석기는 텍스트를 소문자로 변환하고 비-ASCII 문자를 ASCII로 변환해요. 다음 요청은 제공된 텍스트에 커스텀 분석기를 적용해요:
GET /books2/_analyze
{
"analyzer": "lowercase_ascii_folding",
"text": "Le garçon m'a SUIVI."
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "le",
"start_offset" : 0,
"end_offset" : 2,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "garcon",
"start_offset" : 3,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "m'a",
"start_offset" : 10,
"end_offset" : 13,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "suivi",
"start_offset" : 14,
"end_offset" : 19,
"type" : "<ALPHANUM>",
"position" : 3
}
]
}
커스텀 일시적 분석기 적용 (Apply a custom transient analyzer)
토크나이저, 토큰 필터, 문자 필터로 커스텀 일시적(transient) 분석기를 만들 수 있어요. 토큰 필터를 지정하려면 filter 파라미터를 사용하세요. 다음 요청은 uppercase 문자 필터를 사용해 텍스트를 대문자로 변환해요:
GET /_analyze
{
"tokenizer": "keyword",
"filter": [
"uppercase"
],
"text": "OpenSearch filter"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "OPENSEARCH FILTER",
"start_offset" : 0,
"end_offset" : 17,
"type" : "word",
"position" : 0
}
]
}
다음 요청은 html_strip 필터를 사용해 텍스트에서 HTML 문자를 제거해요:
GET /_analyze
{
"tokenizer": "keyword",
"filter": [
"lowercase"
],
"char_filter": [
"html_strip"
],
"text": "<b>Leave</b> right now!"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "leave right now!",
"start_offset" : 3,
"end_offset" : 23,
"type" : "word",
"position" : 0
}
]
}
배열을 사용해 필터를 결합할 수 있어요. 다음 요청은 lowercase 변환과 함께 stopwords 배열의 단어를 제거하는 stop 필터를 결합해요:
GET /_analyze
{
"tokenizer": "whitespace",
"filter": [
"lowercase",
{
"type": "stop",
"stopwords": [
"to",
"in"
]
}
],
"text": "how to train your dog in five steps"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "how",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0
},
{
"token" : "train",
"start_offset" : 7,
"end_offset" : 12,
"type" : "word",
"position" : 2
},
{
"token" : "your",
"start_offset" : 13,
"end_offset" : 17,
"type" : "word",
"position" : 3
},
{
"token" : "dog",
"start_offset" : 18,
"end_offset" : 21,
"type" : "word",
"position" : 4
},
{
"token" : "five",
"start_offset" : 25,
"end_offset" : 29,
"type" : "word",
"position" : 6
},
{
"token" : "steps",
"start_offset" : 30,
"end_offset" : 35,
"type" : "word",
"position" : 7
}
]
}
인덱스 지정 (Specify an index)
인덱스의 기본 분석기로 텍스트를 분석하거나 다른 분석기를 지정할 수 있어요. 다음 요청은 books 인덱스와 연결된 기본 분석기로 제공된 텍스트를 분석해요:
GET /books/_analyze
{
"text": "OpenSearch analyze test"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "opensearch",
"start_offset" : 0,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "analyze",
"start_offset" : 11,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "test",
"start_offset" : 19,
"end_offset" : 23,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
다음 요청은 전체 텍스트 값을 단일 토큰으로 반환하는 keyword 분석기로 제공된 텍스트를 분석해요:
GET /books/_analyze
{
"analyzer": "keyword",
"text": "OpenSearch analyze test"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "OpenSearch analyze test",
"start_offset" : 0,
"end_offset" : 23,
"type" : "word",
"position" : 0
}
]
}
인덱스 필드에서 분석기 도출 (Derive the analyzer from an index field)
텍스트와 인덱스의 필드를 전달할 수 있어요. API는 필드의 분석기를 조회해서 그 분석기로 텍스트를 분석해요. 매핑이 없으면 API는 모든 텍스트를 소문자로 변환하고 공백 기준으로 토큰화하는 standard 분석기를 사용해요. 다음 요청은 name 필드의 매핑을 기준으로 분석을 수행해요:
GET /books2/_analyze
{
"field": "name",
"text": "OpenSearch analyze test"
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "opensearch",
"start_offset" : 0,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "analyze",
"start_offset" : 11,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "test",
"start_offset" : 19,
"end_offset" : 23,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
노멀라이저 지정 (Specify a normalizer)
keyword 필드 대신 인덱스와 연결된 노멀라이저를 사용할 수 있어요. 노멀라이저는 분석 변경이 단일 토큰을 생성하게 해요. 이 예제에서 books2 인덱스는 텍스트를 소문자로 변환하고 비-ASCII 텍스트를 ASCII로 변환하는 to_lower_fold_ascii라는 노멀라이저를 포함해요. 다음 요청은 텍스트에 to_lower_fold_ascii를 적용해요:
GET /books2/_analyze
{
"normalizer": "to_lower_fold_ascii",
"text": "C'est le garçon qui m'a suivi."
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "c'est le garcon qui m'a suivi.",
"start_offset" : 0,
"end_offset" : 30,
"type" : "word",
"position" : 0
}
]
}
토큰 및 문자 필터로 커스텀 일시적 노멀라이저를 만들 수 있어요. 다음 요청은 uppercase 문자 필터를 사용해 주어진 텍스트를 모두 대문자로 변환해요:
GET /_analyze
{
"filter": [
"uppercase"
],
"text": "That is the boy who followed me."
}
위 요청은 다음 필드를 반환해요:
{
"tokens" : [
{
"token" : "THAT IS THE BOY WHO FOLLOWED ME.",
"start_offset" : 0,
"end_offset" : 32,
"type" : "word",
"position" : 0
}
]
}
토큰 세부 정보 조회 (Get token details)
explain 속성을 true로 설정하면 모든 토큰에 대한 추가 세부 정보를 얻을 수 있어요. 다음 요청은 standard 토크나이저와 함께 사용된 reverse 필터에 대한 자세한 토큰 정보를 제공해요:
GET /_analyze
{
"tokenizer": "standard",
"filter": [
"reverse"
],
"text": "OpenSearch analyze test",
"explain": true,
"attributes": [
"keyword"
]
}
위 요청은 다음 필드를 반환해요:
{
"detail" : {
"custom_analyzer" : true,
"charfilters" : [ ],
"tokenizer" : {
"name" : "standard",
"tokens" : [
{
"token" : "OpenSearch",
"start_offset" : 0,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "analyze",
"start_offset" : 11,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "test",
"start_offset" : 19,
"end_offset" : 23,
"type" : "<ALPHANUM>",
"position" : 2
}
]
},
"tokenfilters" : [
{
"name" : "reverse",
"tokens" : [
{
"token" : "hcraeSnepO",
"start_offset" : 0,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "ezylana",
"start_offset" : 11,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "tset",
"start_offset" : 19,
"end_offset" : 23,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
]
}
}
토큰 제한 설정 (Set a token limit)
생성되는 토큰 수의 상한을 설정할 수 있어요. 값을 낮추면 노드의 메모리 사용량이 줄어들어요. 기본값은 10000이에요. 다음 요청은 토큰을 4개로 제한해요:
PUT /books2
{
"settings" : {
"index.analyze.max_token_count" : 4
}
}
위 요청은 analyze API가 아니라 인덱스 API예요. 자세한 내용은 Dynamic index-level index settings를 참고하세요.
응답 본문 필드 (Response body fields)
텍스트 분석 엔드포인트는 다음 응답 필드를 반환해요.
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
tokens |
Array | text에서 도출된 토큰의 배열. token object 참고. |
detail |
Object | 분석과 각 토큰에 대한 세부 정보. 토큰 세부 정보를 요청할 때만 포함돼요. detail object 참고. |
Token object
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
token |
String | 토큰의 텍스트. |
start_offset |
Integer | 원본 텍스트 문자열에서 토큰의 시작 위치. 오프셋은 0부터 시작해요. |
end_offset |
Integer | 원본 텍스트 문자열에서 토큰의 끝 위치. |
type |
String | 토큰의 분류: <ALPHANUM>, <NUM> 등. 보통 토크나이저가 타입을 설정하지만, 일부 필터는 자신만의 타입을 정의해요. 예를 들어 synonym 필터는 <SYNONYM> 타입을 정의해요. |
position |
Integer | tokens 배열에서 토큰의 위치. |
Detail object
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
custom_analyzer |
Boolean | 텍스트에 적용된 분석기가 커스텀인지 내장인지 여부. |
charfilters |
Array | 텍스트에 적용된 문자 필터 목록. |
tokenizer |
Object | 텍스트에 적용된 토크나이저의 이름과, 토큰 필터가 적용되기 전의 내용을 담은 토큰 목록. |
tokenfilters |
Array | 텍스트에 적용된 토큰 필터 목록. 각 토큰 필터는 필터의 이름과 필터 적용 후의 내용을 담은 토큰 목록을 포함해요. 토큰 필터는 요청에 지정된 순서대로 나열돼요. |
토큰 필드 설명은 token object를 참고하세요.
필요한 권한 (Required permissions)
Security 플러그인을 사용한다면 적절한 권한이 있는지 확인하세요: indices:admin/analyze