imok
article thumbnail
728x90

AWS의 Dive into Amazon OpenSearch Service Workshop을 진행하면서 작성한 글입니다.


Amazon OpenSearch Service Domain 시작하기


1. Deployment type

워크숍에서는 프로덕션 수준의 확장성과 안정성이 필요하지 않으므로 Dev/test Template, 단일 AZ로 선택합니다.

Engine Version : 1.3

 

2. Data nodes

  • Number of nodes: 2

복제본 샤드(replica shard)를 사용할 것이기 때문에 기본값인 1 대신 2개의 데이터 노드를 사용합니다.

 

3. Network

  • VPC: (10.0.0.0/16 CIDR 범위가 있는 VPC를 선택합니다.)
  • Subnets: (리스트에 나온 Private 서브넷 중 하나를 선택합니다.)
  • Security groups: SecGrpOSWorkshop 보안 그룹을 선택합니다

4. FGAC(Fine-grained Access Control)

 

5. Access Policy

Only use fine-grained access control을 선택하여 모든 소스에서 도메인에 접근하도록 액세스를 허용하지만, 여전히 FGAC를 통해 자신을 인증해야 합니다 (그래서 도메인은 여전히 ​​안전합니다).

 

 

6. Create Domain

10~15분 정도 지나면 도메인이 생성됩니다.


Amazon OpenSearch Service Domain에 접근하기


Amazon OpenSearch Service 도메인이 생성되고 사용할 준비(Active)가 되면 공용 인터넷에서 도메인에 도달하기 위한 트래픽 경로를 생성해야 합니다.

 

Run Shell Command로 이동해 Command Parameters 섹션에서 configupdate 다음에 OpenSearch Service 도메인의 도메인 엔드포인트를 입력합니다. 

 

Targets 섹션에서 Choose instances manually을 선택하고 표시된 사용 가능한 인스턴스 옆의 체크표시를 선택

 

Output Options 섹션에서 Enable an S3 bucket 옵션을 선택 취소

 

Overall status 에 Success 표시 확인 후 EC2 인스턴스로 이동합니다.

 

Public IPv4 address 섹션에서 open address 링크를 클릭합니다.

 

도메인을 설정할 때 사용한 사용자 이름과 비밀번호를 입력하여 로그인합니다.

 

Private 테넌트를 체크합니다.

 

OpenSearch 도메인 생성이 완료되었습니다. 🙌🏻


검색 & 분석


대시보드 오른쪽 상단의 Dev Tools를 클릭해 영화 웹 사이트에서 쿼리할 데이터를 로드한 다음 직접 쿼리하는 실습을 진행해보겠습니다.

 

Index와 Data 설정

인덱스 생성

데이터를 가져올 인덱스를 만듭니다.

PUT /my-movie-index
{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}

3개의 샤드와 1개의 복제본이 있는 my-movie-index라는 인덱스가 생성됩니다.

 

인덱스 생성 확인

GET /my-movie-index

인덱스에 대한 설정을 확인합니다. 이전에 정의한 샤드 및 복제복의 수생성 시간과 같은 메타데이터를 확인할 수 있습니다.

 

대량 삽입을 사용하여 데이터 채우기

 

OpenSearch의 bulk API 를 통해 데이터를 삽입합니다.

 

imdb-data-for-indexing.txt 

POST /_bulk # bulk API 엔드포인트에 대한 POST 요청
{"index": {"_index": "my-movie-index"}}
{"directors": ["Joseph Gordon-Levitt"], "release_date": "2013-01-18T00:00:00Z", "rating": 7.4, "genres": ["Comedy", "Drama"], "image_url": "http://ia.media-imdb.com/images/M/MV5BMTQxNTc3NDM2MF5BMl5BanBnXkFtZTcwNzQ5NTQ3OQ@@._V1_SX400_.jpg", "plot": "A New Jersey guy dedicated to his family, friends, and church, develops unrealistic expectations from watching porn and works to find happiness and intimacy with his potential true love.", "title": "Don Jon", "rank": 1, "running_time_secs": 5400, "actors": ["Joseph Gordon-Levitt", "Scarlett Johansson", "Julianne Moore"], "year": 2013}
{"index": {"_index": "my-movie-index"}}
{"directors": ["Ron Howard"], "release_date": "2013-09-02T00:00:00Z", "rating": 8.3, "genres": ["Action", "Biography", "Drama", "Sport"], "image_url": "http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg", "plot": "A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.", "title": "Rush", "rank": 2, "running_time_secs": 7380, "actors": ["Daniel Br\u00c3\u00bchl", "Chris Hemsworth", "Olivia Wilde"], "year": 2013}
...

파일은 NDJSON 또는 줄바꿈으로 구분된 JSON으로 구성되어 있습니다. 데이터를 입력할 인덱스를 결정하기 위해 첫 번째 줄을 읽고 다음 줄은 페이로드로 처리됩니다. 

 

 

인데스 설정이 완료되었습니다. 🙌🏻

 


데이터 쿼리하기

심플 쿼리

GET /my-movie-index/_search

쿼리 단계 : 쿼리가 각 샤드에서 로컬로 실행되고 일치하는 문서 ID가 쿼리 노드로 반환됩니다. 쿼리 노드는 이러한 레코드를 병합하고 정렬된 목록을 만듭니다.

패칭 단계 : 쿼리 노드는 ID에서 실제 데이터를 가져와 클라이언트에 반환합니다.

OpenSearch를 사용할 때 JSON API를 가장 자주 사용하게 됩니다. 아래 URL 기반 쿼리를 실행해 쿼리 매개변수로 간단한 검색을 실행합니다.

GET /my-movie-index/_search?q=franco

반환된 데이터에는 결과 집합과 함께 여러 정보가 포함되어 있습니다.

 

{
  "took" : 11,            // Server-side 실행시간. 밀리세컨드
  "timed_out" : false,    // 쿼리수행의 타임아웃 여부
  "_shards" : {           
    "total" : 3,          // 쿼리된 인덱스의 총 샤드 수
    "successful" : 3,     // 쿼리에 성공적으로 응답한 샤드 수
    "skipped" : 0,        // 스킵 된 샤드 수
    "failed" : 0          // 검색에 실패한 샤드 수
  },
  "hits" : {                
    "total" : {
      "value" : 13,       // 발견된 관련 문서 수
      "relation" : "eq"   // Search 방식, 디폴트는 eq
    }
  }
}

 

Term 쿼리

term 쿼리는 검색어와 정확히 일치하는 문서를 반환합니다. 

GET my-movie-index/_search
{
  "query": {
    "term": {
      "directors.keyword": {
        "value": "James Franco"
      }
    }
  }
}

 

Keyword를 이용한 쿼리하기

  • Term 쿼리 - 용어를 정확히 일치시키려는 경우 이 쿼리 계열을 사용합니다. keyword 필드와 함께 용어 쿼리를 자주 사용합니다.
  • Match 쿼리 - 긴 텍스트에서 매칭하고 특히 OpenSearch의 관련성을 사용하여 결과를 정렬할 때 이 쿼리 계열을 사용합니다. text 필드와 함께 이러한 쿼리를 가장 자주 사용합니다.
GET my-movie-index/_search
{
  "query": {
    "term": {
      "title": "transformers"
    }
  }
}

 

GET my-movie-index/_analyze
{
  "analyzer": "default",
  "text": ["Transformers"]
}

_analyze API를 사용하여 OpenSearch가 입력한 텍스트를 어떻게 변환하는지 확인할 수 있습니다.

 

Boolean 쿼리

bool 쿼리는 복합 쿼리 클래스의 구성원으로 여러 term과 match 쿼리를 혼합하여 일치 항목을 결합하는 방법에 대한 로직을 제공합니다. 

GET /my-movie-index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "genres": "action"
          }
        },
        {
          "match": {
            "title": "matrix"
          }
        },
        {
          "match": {
            "actors": "reeves"
          }
        }
      ]
    }
  }
}

결과 집합의 맨 위에 정렬된 문서는 score 값이 가장 높은 문서였습니다. 이 경우 문서는 3가지 should 조건 모두와 일치합니다.

특정 문서가 받은 점수의 이유를 이해하려면 explain 쿼리(explain=true) 를 수행할 수 있습니다. 

 

Range 쿼리

Range 쿼리는 숫자 값에 대해 동작하며 쿼리에서 지정한 범위에 속하는 일치 항목을 반환합니다. 

  • 보다 큼: gt
  • 보다 작음: lt
  • 크거나 같음: gte
  • 작거나 같음: lte
GET my-movie-index/_search
{
  "query": {
    "range": {
      "year": {
        "gt": 2014,
        "lt": 2016
      }
    }
  }
}

 

Boost 쿼리

OpenSearch는 점수 알고리즘을 사용하여 문서를 반환하기 전에 점수를 매기고 정렬합니다. boosting 을 사용하여 점수에 영향을 줄 수 있습니다. 필드를 부스트하면 해당 필드에서 일치하는 용어의 점수에 부스트 계수를 곱합니다.

GET my-movie-index/_search
{
  "query": {
    "multi_match": {
      "query": "horror",
      "fields": ["title^2","plot"]
    }
  }
}

title 필드에서 일치 항목의 가중치를 높임

 

Function Score 쿼리

function_score 쿼리를 사용하면 필드 값, TF/IDF 점수 그리고 Gaussian , exponential , _linear_와 같은 Decay 함수, 심지어 Painless 스크립팅 언어의 스크립트까지 혼합할 수 있는 함수를 정의할 수 있습니다.

POST my-movie-index/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "horror",
          "fields": [
            "title"
          ]
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "rating",
            "missing": 0
          }
        }
      ]
    }
  },
  "sort": [
    {
      "_score": {
        "order": "asc"
      }
    }
  ]
}

 rating 필드가 소스 문서에 존재하지 않는 경우 문서의 점수에 0이 곱해집니다.

 sort 키워드를 사용하여 점수별로 결과를 오름차순 으로 정렬합니다.

 

Aggregation 쿼리

집계는 특정 필드의 값을 그룹화하여 요약된 값을 계산합니다. 

GET my-movie-index/_search
{
  "aggs": {
    "term_agg": {
      "terms": {
        "field": "genres.keyword"
      }
    }
  },
  "size": 0
}


OpenSearch 대시보드의 Discover 메뉴

OpenSearch 대시보드의 Discover 메뉴를 통해 동일한 검색 쿼리를 수행할 수 있는 방법을 살펴봅니다.

 

인덱스 패턴 셋업

인덱스 패턴을 생성하면 Dashboards가 데이터에 대한 시간 기반 액세스를 관리합니다.

모든 인덱스를 마치 하나의 인덱스인 것처럼 인덱스 패턴으로 명명해서 취급할 수 있습니다.

 

Dashboard > Discover 클릭

my-movie-index 와 일치하는 인덱스가 표시됩니다.

timestamp 필드를 자동으로 검색하고 전역 시간 필드를 선택하는 옵션을 제공합니다.
release_date를 선택하고 Create index pattern를 클릭합니다.

Discover 클릭 > Last 15 minutes 텍스트를 클릭 > Minutes ago을 Years ago으로 변경 > Update를 클릭

 

Discover에서 검색하기

1. Search 필드에 franco 입력하고 Refresh을 클릭합니다.

2. directors: franco 입력하고 Refresh을 클릭합니다.

3.  NOT genres: [drama, action, comedy] 입력 후 Update 클릭

검색 상자에 쿼리를 입력하면 Dashboards가 텍스트 쿼리를 OpenSearch DSL로 변환합니다. 

오른쪽 상단 모서리에서 Inspect를 클릭한 다음 Request을 클릭하여 쿼리 DSL 쿼리를 볼 수 있습니다

 

 

728x90
profile

imok

@imok2

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!