ELASTICSEARCH

[엘라스틱서치] 7. object, Geo 위치정보

sejin2 2024. 3. 14. 09:55

Object

movie로 조회하면 안 나옴. movie.name해야만 값이 조회가 됨

→ name은 Loki이고, side는 villain인 문서를 검색

GET movies/_search
{
  "query":{
    "bool":{
      "must":[
      {
        "match":{
          "movie.name":"Loki"
        }
      },
      {
        "match":{
          "movie.side":"villain"
        }
      }
      ]
    }
  }
}

name이 Loki인 것을 가지고 오고, 그 이후에 side가 villain인 것 가지고 온다.

결과 -> 2개의 문서를 가지고 온다.

{
  "took": 15,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1.0142183,
    "hits": [
      {
        "_index": "movies",
        "_id": "3",
        "_score": 1.0142183,
        "_source": {
          "title": "Avengers : Infinity War",
          "movie": [
            {
              "name": "Loki",
              "side": "superhero"
            },
            {
              "name": "Thanos",
              "side": "villain"
            }
          ]
        }
      },
      {
        "_index": "movies",
        "_id": "2",
        "_score": 0.75948024,
        "_source": {
          "title": "The Avengers",
          "movie": [
            {
              "name": "Iron Man",
              "side": "superhero"
            },
            {
              "name": "Loki",
              "side": "villain"
            },
            {
              "name": "Spider Man",
              "side": "superhero"
            }
          ]
        }
      }
    ]
  }
}

내가 원하는 결과 1개의 문서를 검색하기 위해서 nested를 사용

  • nested : 내부에 있는 object값들을 서로 다른 역색인을 만든다. 

1. 구조 만들기

PUT movies2 
{
  "mappings":{
    "properties":{
      "movie":{
        "type":"nested",
        "properties":{
          "name":{
            "type":"text"
          },
          "side":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

2. 데이터 넣기

PUT movies2/_doc/2
{
  "title":"The Avengers",
  "movie":
  [
    {
      "name":"Iron Man",
      "side":"superhero"
    },
    {
      "name":"Loki",
      "side":"villain"
    },
    {
      "name":"Spider Man",
      "side":"superhero"
    }
  ]
}

PUT movies2/_doc/3
{
  "title":"Avengers : Infinity War",
  "movie":[ 
    {
      "name":"Loki",
      "side":"superhero"
    },
    {
      "name":"Thanos",
       "side":"villain"
    }
  ]
}

3. 검색

GET movies2/_search
{
  "query":{
    "nested" : {
      "path":"movie",
      "query":{
        "bool":{
          "must":[
            {
              "match":{
                "movie.name":"Loki"
              }
            },
            {
              "match":{
                "movie.side":"villain"
              }
            }
          ]
        }
      }
    } 
  }
}

4. 결과

{
  "took": 749,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.8668083,
    "hits": [
      {
        "_index": "movies2",
        "_id": "2",
        "_score": 1.8668083,
        "_source": {
          "title": "The Avengers",
          "movie": [
            {
              "name": "Iron Man",
              "side": "superhero"
            },
            {
              "name": "Loki",
              "side": "villain"
            },
            {
              "name": "Spider Man",
              "side": "superhero"
            }
          ]
        }
      }
    ]
  }
}

 

Geo 위치정보

PUT geo_index/_doc/1
{
  "location":{
    "lat":42.35548,
    "lon":3.46534
  }
}

mapping type을 넣지 않으면, 기본으로 float이 들어간다.

GET geo_index/_mapping
매핑조회 -->

{
  "geo_index": {
    "mappings": {
      "properties": {
        "location": {
          "properties": {
            "lat": {
              "type": "float"
            },
            "lon": {
              "type": "float"
            }
          }
        }
      }
    }
  }
}

---> geo_point 지정

PUT geo_index2
{
  "mappings":{
    "properties":{
      "locatin":{
        "type":"geo_point"
      }
    }
  }
}
PUT geo_index2/_doc/1
{
  "location":{
    "lat":42.35548,
    "lon":3.46534
  }
}
GET geo_index2/_mapping
{
  "geo_index2": {
    "mappings": {
      "properties": {
        "locatin": {
          "type": "geo_point"
        },
        "location": {
          "properties": {
            "lat": {
              "type": "float"
            },
            "lon": {
              "type": "float"
            }
          }
        }
      }
    }
  }
}

type이 geo_point로 바뀐 것을 볼 수 있다.

- 여러개의 데이터 넣기

put geo_index3/_bulk 
{"index":{"_id":"1"}}
{"station":"강남","location":{"lon":127.027926,"lat":37.497175},"line":"2호선"}
{"index":{"_id":"2"}}
{"station":"종로3가","location":{"lon":126.991806,"lat":37.571607},"line":"3호선"}
{"index":{"_id":"3"}}
{"station":"여의도","location":{"lon":126.924191,"lat":37.521624},"line":"5호선"}
{"index":{"_id":"4"}}
{"station":"서울역","location":{"lon":126.972559,"lat":37.554648},"line":"1호선"}

geo_bounding_box 검색 : 사각형 박스 안에 들어온 위치 검색

GET geo_index3/_search
{
  "query":{
    "geo_bounding_box":{
      "location":{
        "bottom_right":{
          "lat":37.5555,
          "lon":127.02222
        }, 
        "top_left":{
          "lat":37.58888,
          "lon":126.9888
        }
      }
    }
  }
}

-> geo_distance 검색 : 포인트와 거리를 주면 거리가 반지름으로 원형을 만들어 그 원 안의 위치 검색

GET geo_index3/_search
{
  "query":{
    "geo_distance":{
      "distance":"5km",
      "location":{
        "lat":37.53333,
        "lon":126.966666
      }
    }
  }
}

-> geo_shape : 여러 개의 포인터를 연결하여 면 안에 들어오는 위치 검색