Elasticsearch 기본 쿼리

2020. 8. 20. 16:54개발 이야기

개요

Elasticsearch cloud Seoul region이 2020년 8월에 출시했다.
현재 14일 무료 plan으로 테스트해보고 있다.
아래 내용은 모두 Elasticsearch 7.8에서 테스트 했다.

인덱스 생성

샤드는 1개, 레플리카는 0개로 설정한다.

PUT /$index

{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 0
    }
  }
}

인덱스 생성 - mapping 정보 함께 생성

mapping정보를 입력하지 않은 index에는 PUT /$index/$type/$id와 같이 데이터 입력이 가능하다.
하지만 mapping정보까지 입력한 index에 데이터 입력시 에러가 발생할 수 있다.
Elasticsearch 6.0부터는 하나의 type만 지원되기 때문에 이후 데이터 입력시 /$index/_doc/$id로 해야 가능한다.

PUT /$index

{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 0
    }
  },
  "mappings": {
    "properties": {
      "rating": {
        "type": "long"
      },
      "reference": {
        "properties": {
          "name": {
            "type": "text"
          },
            "url": {
                "type": "text"
            }
        }
      },
      "type": {
        "type": "keyword"
      },
      {...},
      {...},
      {...}
    }
  }
}

여러 field에서 검색

POST /$index/_doc/_search

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*검색어*",
            "fields": [
              "필드명1",
              "필드명2",
              "필드명3"
            ]
          }
        }
      ]
    }
  }
}

여러 field검색 AND 특정 field값 조건 추가

{
  "size": 2,
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*하*",
            "fields": [
              "필드명1",
              "필드명2",
              "필드명3"
            ]
          }
        },
        {
          "term": {
            "필드명": "필드값"
          }
        }
      ]
    }
  }
}

특정 field가 존재하는 document 검색

GET /$index/_doc/_search

{
  "query": {
    "exists": {
      "field": "images"
    }
  }
}

특정 field의 특정 값이 존재하는 document 찾기

GET /$index/_doc/_search

{
  "query": {
    "term": {
        "필드명": "값"
    }
  }
}

특정 field 삭제

POST /$index/_doc/_update_by_query

{
    "script" : "ctx._source.remove('필드명')",
    "query" : {
        "exists": { "field": "필드명" }
    }
}

특정 field가 존재하지 않는 document 찾기

GET /$index/$type/_search

{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "필드명"
          }
        }
      ]
    }
  }
}

document 전체 삭제

POST /$index/_doc/_delete_by_query

{
  "query": {
    "match_all": {}
  }
}

혹은

DELETE /$index/_doc/_query

{
  "query": {
    "match_all": {}
  }
}

검색 결과를 특정 field로 aggregate하여 각 개수를 확인하기

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*검색어*",
            "fields": [
              "필드명1",
              "필드명2",
              "필드명3"
            ]
          }
        }
      ]
    }
  },
  "aggs": {
    "my_aggregate_result": {
      "terms": {
        "field": "aggregate할 필드명"
      }
    }
  }
}

검색 결과 top_hits 사용

네이버처럼 블로그, 지식인, 카페별 검색 결과를 출력할 때 유용할 것 같다.

GET /$index/_doc/_search

{
  "size": 0,
  "query": {
    "bool": {
      "must": {
        "query_string": {
          "query": "*검색어*",
          "fields": [
            "필드명"
          ]
        }
      }
    }
  },
  "aggs": {
    "top_tags": {
      "terms": {
        "field": "그룹핑 할 필드명",
        "size": 5 // 그룹핑 한 결과 개수
      },
      "aggs": {
        "my_top_hits": {
          "top_hits": {
            "size": 5, // 그룹별 개수
            "_source": { // 출력할 내용을 필터링하고 싶으면 `_source`를 추가한다.
              "includes": [ 
                "type",
                "title"
              ]
            }
          }
        }
      }
    }
  }
}