반응형
Recent Posts
Recent Comments
관리 메뉴

개발잡부

[es] nested query test 본문

ElasticStack/Elasticsearch

[es] nested query test

닉의네임 2022. 6. 21. 15:30
반응형
{'_shards': {'failed': 0, 'skipped': 0, 'successful': 1, 'total': 1},
 'aggregations': {'price_aggs_filter': {'doc_count': 7,
                                        'price_filter': {'doc_count': 4,
                                                         'price_avg': {'value': 12675.0}}}},
 'hits': {'hits': [{'_id': '2',
                    '_index': 'nested-index',
                    '_score': 1.2057104,
                    '_source': {'name': '소고기 1등급 100g',
                                'store': [{'code': '0002', 'price': 9800}]},
                    '_type': '_doc',
                    'sort': [1.2057104, 9800]},
                   {'_id': '5',
                    '_index': 'nested-index',
                    '_score': 1.2057104,
                    '_source': {'name': '소고기 1등급 100g',
                                'store': [{'code': '0001', 'price': 11100},
                                          {'code': '0002', 'price': 11000},
                                          {'code': '0003', 'price': 11000}]},
                    '_type': '_doc',
                    'sort': [1.2057104, 11000]},
                   {'_id': '1',
                    '_index': 'nested-index',
                    '_score': 1.2057104,
                    '_source': {'name': '소고기 1등급 100g',
                                'store': [{'code': '0001', 'price': 11000},
                                          {'code': '0002', 'price': 11100}]},
                    '_type': '_doc',
                    'sort': [1.2057104, 11100]},
                   {'_id': '10',
                    '_index': 'nested-index',
                    '_score': 1.2057104,
                    '_source': {'name': '소고기 1등급 200g',
                                'store': [{'code': '0002', 'price': 18800}]},
                    '_type': '_doc',
                    'sort': [1.2057104, 18800]}],
          'max_score': None,
          'total': {'relation': 'eq', 'value': 4}},
 'timed_out': False,
 'took': 44}

 

data.json 

[
  {
    "name": "소고기 1등급 100g",
    "store": [
      {
        "code": "0001",
        "price": 11000
      },
      {
        "code": "0002",
        "price": 11100
      }
    ]
  },
  {
    "name": "소고기 1등급 100g",
    "store": [
      {
        "code": "0002",
        "price": 9800
      }
    ]
  },
  {
    "name": "소고기 3등급 100g",
    "store": [
      {
        "code": "0001",
        "price": 8000
      },
      {
        "code": "0002",
        "price": 8100
      }
    ]
  },
  {
    "name": "소고기 2등급 100g",
    "store": [
      {
        "code": "0001",
        "price": 9000
      },
      {
        "code": "0002",
        "price": 9100
      }
    ]
  },
  {
    "name": "소고기 1등급 100g",
    "store": [
      {
        "code": "0001",
        "price": 11100
      },
      {
        "code": "0002",
        "price": 11000
      },
      {
        "code": "0003",
        "price": 11000
      }
    ]
  },
  {
    "name": "소고기 1등급 100g",
    "store": [
      {
        "code": "0003",
        "price": 9900
      }
    ]
  },
  {
    "name": "소고기 3등급 100g",
    "store": [
      {
        "code": "0002",
        "price": 8300
      },
      {
        "code": "0003",
        "price": 8200
      }
    ]
  },
  {
    "name": "소고기 2등급 100g",
    "store": [
      {
        "code": "0002",
        "price": 9300
      },
      {
        "code": "0003",
        "price": 9200
      }
    ]
  },
  {
    "name": "소고기 1등급 200g",
    "store": [
      {
        "code": "0001",
        "price": 18800
      }
    ]
  },
  {
    "name": "소고기 1등급 200g",
    "store": [
      {
        "code": "0002",
        "price": 18800
      }
    ]
  }
]

 

 

nested_test.py

from elasticsearch import Elasticsearch
import pprint as ppr
import json

index_name ="nested-index"

class EsAPI:
    es = Elasticsearch(hosts="localhost", port=9200, http_auth=('elastic', 'elastic1!'))  # 객체 생성
    @classmethod
    def srvHealthCheck(cls):
        health = cls.es.cluster.health()
        print (health)

    @classmethod
    def allIndex(cls):  # Elasticsearch에 있는 모든 Index 조회
        print (cls.es.cat.indices())

    @classmethod
    def dataInsert(cls):
        # ===============
        # 데이터 삽입
        # ===============
        with open("/Users/doo/doo_py/homeplus/data/nested/data.json", "r", encoding="utf-8") as fjson:
            data = json.loads(fjson.read())

            for n, i in enumerate(data):
                doc = {
                    "name": i['name'],
                    "store": i["store"]
                }
                res = cls.es.index(index=index_name, doc_type="_doc", id=n + 1, body=doc)
                print (res)

    @classmethod
    def searchAll(cls, indx=None):  # ===============        # 데이터 조회 [전체]        # ===============
        res = cls.es.search(
            index=index_name,
            doc_type="_doc",
            body={"query": {"match_all": {}}})
        print (json.dumps(res, ensure_ascii=False, indent=4))

    @classmethod
    def searchFilter(cls):
        # ===============        # 데이터 조회 []        # ===============
        res = cls.es.search(
            index=index_name,
            doc_type="_doc",
            body= {
                "sort": [
                    "_score",
                    {
                        "store.price": {
                            "mode": "max",
                            "order": "asc",
                            "nested": {
                                "path": "store",
                                "filter": {
                                    "term": {
                                        "store.code": "0002"
                                    }
                                }
                            }
                        }
                    }
                ],
                "query": {
                    "bool": {
                        "must": [
                            {
                                "match": {
                                    "name": {
                                        "query" : "소고기 1등급",
                                        "operator": "and"
                                    }
                                }
                            },
                            {
                                "nested": {
                                    "path": "store",
                                    "query": {
                                        "bool": {
                                            "must": [
                                                {
                                                    "match": {
                                                        "store.code": "0002"
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        ]
                    }
                },
                "aggs": {
                    "price_aggs_filter": {
                        "nested": {
                            "path": "store"
                        },
                        "aggs": {
                            "price_filter": {
                                "filter": {
                                    "term": {
                                        "store.code": "0002"
                                    }
                                },
                                "aggs": {
                                    "price_avg": {
                                        "avg": {
                                            "field": "store.price"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        )
        ppr.pprint(res)

    @classmethod
    def createIndex(cls):
        # ===============        # 인덱스 생성        # ===============
        cls.es.indices.create(
            index=index_name,
            body={
                    "settings": {
                        "index.number_of_shards": 1,
                        "index.number_of_replicas": 0
                    },
                    "mappings": {
                        "properties": {
                            "name": {
                                "type": "text"
                            },
                            "store": {
                                "type": "nested"
                            }
                        }
                    }

            }
        )


# EsAPI.allIndex()
# EsAPI.srvHealthCheck()
# EsAPI.createIndex()
# EsAPI.dataInsert()
# EsAPI.searchAll()
EsAPI.searchFilter()
반응형

'ElasticStack > Elasticsearch' 카테고리의 다른 글

[es] Similarity module  (0) 2022.06.24
[es] Nested Query vs Object Query  (0) 2022.06.21
[es] 스코어 계산 확인 - explain  (0) 2022.06.20
[es] analyzer test  (0) 2022.06.19
[es] payload-score 7.15.1 gradle  (0) 2022.05.22
Comments