Open kgneng2 opened 3 years ago
PUT /my_index/default/_mapping
{
"properties": {
"description": {
"type":"text",
"analyzer":"my_custom_analyzer"
},
"teaser":{
"type":"text",
"analyzer": "standard"
}
}
}
POST /my_index/default/1
{
"description":":)",
"teaser":":)"
}
GET /my_index/default/_search
{
"query": {
"match": {
"description":"_happy_"
}
}
}
"description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
"details": [
{
"value": 1,
"description": "termFreq=1.0",
"details": [
]
},
{
"value": 1.2,
"description": "parameter k1",
"details": [
]
},
{
"value": 0.75,
"description": "parameter b",
"details": [
]
},
{
"value": 6.9182334,
"description": "avgFieldLength",
"details": [
]
},
{
"value": 4,
"description": "fieldLength",
"details": [
]
}
"description" : idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
"details": [
{
"value": 448,
"description": "docFreq",
"details": [
]
},
{
"value": 1012159,
"description": "docCount",
"details": [
]
}
]
TF * IDF 값이 최종 스코어를 의미한다.
GET _mapping
{
"autocomplete_test_1" : {
"mappings" : {
"properties" : {
"word" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
},
"analyzer" : "linguist2_analyzer"
}
}
}
}
}
스팀게임 추
검색시, text로만 구성되면 검색이 되지않지만, keyword와 같이해준다면 검색이 가능하기 때문이다.
추천만 검색했을시 keyword는 불일치지만, text 일때 걸리기때문에 매핑이 가능함.
https://renuevo.github.io/elastic/autocomplete/elastic-autocomplete-1/
두개의 방법이 있는거같다.
PUT autocomplete_test_2 { "settings": { "analysis": { "analyzer": { "autocomplete": { "tokenizer": "autocomplete", "filter": [ "lowercase" ] }, "autocomplete_search": { "tokenizer": "lowercase" } }, "tokenizer": { "autocomplete": { "type": "edge_ngram", "min_gram": 1, "max_gram": 20, "token_chars": [ "letter", "digit" ] } } } }, "mappings": { "properties": { "word": { "type": "text", "analyzer": "autocomplete", "search_analyzer": "autocomplete_search" } } } }
2. ES에서 제공해주는 suggest를 활용한다.
For instance, when querying the first_name and last_name fields for “Will Smith”, the best match is likely to have “Will” in one field and “Smith” in the other.
{
"multi_match" : {
"query": "Will Smith",
"type": "best_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
(+first_name:will +first_name:smith)
| (+last_name:will +last_name:smith)
첫 번째는 Most_field type은 field마다 Operator, minimum_should_match를 적용하지만 Cross_fields type은 Term마다 적용한다.
두 번째는 관련성이다. 만약 “Will Smith”이라는 이름을 검색한다고 생각해보자. 검색 시 ‘Will’, ‘Smith’이라는 두개의 Terms는 각 각의 last_name, first_name Field에 대해 검색할 것이다. 결과는 ”Smith Jones”가 “Will Smith” 보다 점수가 높을 것이다.
{
"explain": true,
"query": {
"bool": {
"must": {
"match": {
"CountryCode": "KR"
}
},
"should": [
{
"terms": {
"hotelId": [
"4757718",
"4943464",
"4996410",
"5257994",
"5279852",
"5281864",
"5281890"
]
}
},
{
"match": {
"placeKo": "화성시"
}
},
{
"multi_match": {
"query": "스타즈호텔 동탄",
"fields": [
"nameKo",
"featuredNameKo",
"normNameKo",
"baseNameKo"
],
"type": "cross_fields",
"minimum_should_match": "100%",
"analyzer": "query_ko"
}
},
{
"multi_match": {
"query": "staz hotel dongtan",
"fields": [
"nameEn",
"featuredNameEn",
"normNameEn",
"baseNameEn"
],
"type": "cross_fields",
"minimum_should_match": "50%",
"analyzer": "query_en"
}
}
]
}
}
}
이거어떠카냐..
예시 sample
{
"settings": {
"analysis": {
"filter": {
"hotel_synonym": {
"type": "synonym",
"synonyms_path": "analysis/hotel_synonym.txt"
}
},
"analyzer": {
"autocomplete": {
"tokenizer": "autocomplete",
"filter": [
"lowercase",
"hotel_synonym"
]
},
"autocomplete_search": {
"tokenizer": "lowercase"
}
},
"tokenizer": {
"autocomplete": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"properties": {
"word": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "autocomplete_search"
}
}
}
}
tokenizer 를 진행하면 일단 짜름 filter를 하면 tokenizer된거에대해서 map함수를 갈김
GET _analyze
{
"tokenizer": "standard",
"text": "메리어트 뉴욕"
}
{
"tokens" : [
{
"token" : "메리어트",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "뉴욕",
"start_offset" : 5,
"end_offset" : 7,
"type" : "<HANGUL>",
"position" : 1
}
]
}
GET _analyze
{
"tokenizer": "standard",
"filter": [
{
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
],
"text": "메리어트 뉴욕"
}
{
"tokens" : [
{
"token" : "메",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "메리",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "메리어",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "메리어트",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "뉴",
"start_offset" : 5,
"end_offset" : 7,
"type" : "<HANGUL>",
"position" : 1
},
{
"token" : "뉴욕",
"start_offset" : 5,
"end_offset" : 7,
"type" : "<HANGUL>",
"position" : 1
}
]
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer.html
A search_analyzer setting for non-phrase queries that will remove stop words
A search_quote_analyzer setting for phrase queries that will not remove stop words
{
"autocomplete_test_2" : {
"aliases" : { },
"mappings" : {
"properties" : {
"word" : {
"type" : "text",
"analyzer" : "autocomplete",
"search_analyzer" : "autocomplete_search"
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "1",
"provided_name" : "autocomplete_test_2",
"creation_date" : "1619084078796",
"analysis" : {
"analyzer" : {
"autocomplete" : {
"filter" : [
"lowercase"
],
"tokenizer" : "autocomplete"
},
"autocomplete_search" : {
"tokenizer" : "lowercase"
}
},
"tokenizer" : {
"autocomplete" : {
"token_chars" : [
"letter",
"digit"
],
"min_gram" : "1",
"type" : "edge_ngram",
"max_gram" : "20"
}
}
},
"number_of_replicas" : "1",
"uuid" : "-8FO42iGTzyvqlEuurgttw",
"version" : {
"created" : "7100299"
}
}
}
}
}
GET autocomplete_test_2/_search
{
"explain": true,
"query" :{
"match": {
"word": "여성 트레인"
}
}
}
여성속옷이 더 높은 결과를 도출, 이유는 "dl, length of field", 이 값 수치가 여성트레이닝복 보다 작기때문 오타로 인한(?) 또는 자모분리가 안된 ngram 분리일 경우 발생하는 현상입니다.
해결책은 fuziness를 도입하거나, 한글 자모 분리값을 이용해 보도록합니다.
| Analysis settings to define the custom autocomplete analyzer.
| The text field uses the autocomplete analyzer at index time, but the standard analyzer at search time.
| This field is indexed as the terms: [ q, qu, qui, quic, quick, b, br, bro, brow, brown, f, fo, fox ]
| The query searches for both of these terms: [ quick, br ]
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/query-dsl-match-bool-prefix-query.html
match-bool-prefix
GET /_search
{
"query": {
"match_bool_prefix" : {
"message" : "quick brown f"
}
}
}
GET /_search
{
"query": {
"bool" : {
"should": [
{ "term": { "message": "quick" }},
{ "term": { "message": "brown" }},
{ "prefix": { "message": "f"}}
]
}
}
}
analyzer는 기본 매핑된 analyzer를 이용함니다.
기본적으로 Charfilter 에 의해 공백 콤마등의 문자는 제거 한다.
standard analyzer를 사용한다.
standard tokenizer
letter tokenizer
lowercase => letter + 소문자 변경 진행
edge n gram tokenizer
shingle
req
"output_unigrams": false
: 추가시 한단어 짜리는 안나옴. min_shingle_size, max_shingle_size만 포함res
token filter
standard token filter
stop token filter
Query