LoginSignup
8
2

More than 1 year has passed since last update.

OpenSearch でいろいろやってみる ~インデックス編~

Last updated at Posted at 2021-12-16

インデックス編

OpenSearchを触ってみた個人的メモ代わりです。

  1. OpenSearch でいろいろやってみる ~インストール編~
  2. OpenSearch でいろいろやってみる ~インデックス編~ (👈ココ)
  3. OpenSearch でいろいろやってみる ~絞り込み編~
  4. OpenSearch でいろいろやってみる ~Aggregation編~

データを入れてみる

データの投入、ここがキモだと思ってる。主にマッピング。
RDBMS では SQL により、「正規化」されたデータを「取得する」時に如何様にも操作できるが、
検索エンジン等、多くの NoSQL では、データを適宜「非正規化」して「作る」時に、どういう目的でデータを扱うのか、どういう形で取れるかが決まる。
どっちが良いという話ではなく、思想からしてまるっきり違うということなので慎重に。

マッピングしてみる

今回は、EC サイト等で見かけるレビューのデータを作ってみようと思う。
レビューのタイトル、本文、商品名、1 ~ 5 までの星数...などのフィールドが考えられる。
以下のようにしてみた。

mappings
PUT reviews
{
  "mappings": {
    "properties": {
      "title": {
        "type": "keyword"
      },
      "comment": {
        "type": "text",
        "fielddata": true,
        "analyzer": "kuromoji",
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      },
      "user_name": {
        "type": "keyword"
      },
      "star": {
        "type": "integer"
      },
      "product_cd": {
        "type": "keyword"
      },
      "product_name": {
        "type": "keyword"
      },
      "review_date": {
        "type": "date"
      },
      "is_purchased": {
        "type": "boolean"
      },
      "attrs": {
        "type": "nested",
        "properties": {
          "attrs.name": { "type": "keyword" },
          "attrs.answer": { "type": "keyword" }
        }
      }
    }
  }
}

例えば商品の下にレビューをArrayでネストさせて。。。
みたいな形も場合によってはあり得そうだが
今回は自由が利きそうなフラットな形で。

ポイントとしては、任意の属性をattrs としてをネストしているところ、
将来的に全文検索に使えそうな一部フィールドに analyze 設定をしているところ。
本格的に集計・分析に使用する場合はまた違ってくるかもしれないが、
検索・絞り込みメインでとりあえず。

データを投入してみる

下記のような形式で一括投入可能

_bulk
POST _bulk
{ "index": { "_index": "インデックス名", "_id": "一意のID" } }
{ データのjson }
{ "index": { "_index": "インデックス名", "_id": "一意のID" } }
{ データのjson }
...

_id は任意の値で良ければ省略できる。
_index も予め指定しておけば省略可(POST {インデックス名}/_bulk)
成功すれば"errors" : falseでレスポンスがあるはず。

確認

幾つかデータを入れて試しにクエリー投げてみる。

request
GET reviews/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "product_cd": {
              "value": "SAMPLE0001"
            }
          }
        }
      ]
    }
  }
}

↓返ってきた!

response
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 0.24116206,
    "hits" : [
      {
        "_index" : "reviews",
        "_type" : "_doc",
        "_id" : "x5XuIn0B1dg6kvEPVSz5",
        "_score" : 0.24116206,
        "_source" : {
          "title" : "1番目のレビュータイトル",
          "comment" : "レビューのコメントです。いい感じです。",
          "user_name" : "ダミーユーザー1",
          "star" : 1,
          "product_cd" : "SAMPLE0001",
          "product_name" : "サンプル商品",
          "review_date" : "2021-11-19T12:00:00",
          "is_purchased" : true,
          "attrs" : [
            {
              "name" : "年代",
              "answer" : "10代"
            },
            {
              "name" : "性別",
              "answer" : "男性"
            },
            {
              "name" : "お住まい",
              "answer" : "北海道"
            }
          ]
        }
      },
      {
        "_index" : "reviews",
        "_type" : "_doc",
        "_id" : "yJXuIn0B1dg6kvEPVSz5",
        "_score" : 0.24116206,
        "_source" : {
 省略 

エイリアス

現時点では省略するが、aliasも設定した方が良さ気。
alias:indexは1:Nで定義可能で、indexを分散管理した上でalias指定で横断的に引っ張ってきたりできるみたい。

alias
POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "foo_reviews",
        "alias": "all_reviews"
      }
    },
    {
      "add": {
        "index": "bar_reviews",
        "alias": "all_reviews"
      }
    }
  ]
}
8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2