LoginSignup
5
6

More than 5 years have passed since last update.

Elasticsearchで1対多のデータを入れる時

Posted at

画像とタグやメッセージとそのコメントなど1対多の関係があるデータをelasticsearchに入れて検索させたい場合、nestedを使うというメモ

主に使ったもの

Elasticsearch5
elasticsearch-rails

indexの作成

nested queryを使いたい場合、indexを作成する時はelasticsearch-railsを使って以下のように書きます。

    mapping _source: { enabled: true },
      _all: { enabled: true, analyzer: "kuromoji_analyzer" } do
      indexes :id,             type: 'long', index: 'not_analyzed'
      indexes :body,           type: 'string', analyzer: 'kuromoji_analyzer'
      indexes :comments, type: 'nested' do
        indexes :user_id,      type: 'long'
        indexes :message_id,   type: 'long'
        indexes :body,         type: 'string', analyzer: 'kuromoji_analyzer'
      end
      indexes :created_at,     type: 'date'
      indexes :updated_at,     type: 'date'
    end

こう書くことでcommentsのところが

"comments":{
  "type":"nested", "properties":{
                     "user_id":{"type":"long"},
                     "message_id":{"type":"long"},
                     "body":{"type":"string","analyzer":"kuromoji_analyzer"}
                   }
}

以下のようなindex定義でElasticsearchに登録されます。

検索する時のquery

例ばbodyとcomments.bodyの二つのカラムの中のどれかにキーワード検索したい場合、以下のように書くと検索できます。

{
  "query":{
    "bool":{
      "must":[
        {"term":{"school_id":1}}
      ],
      "should":[
        {
          "simple_query_string":{
            "query":""テスト投稿"",
            "fields":["body"],
            "default_operator":"and"
          }
        },
        {
          "nested":{   <<<<<<<< ここに注目
            "path":"comments",
            "query":{
              "simple_query_string":{
                "query":""テスト投稿"",
                "fields":["comments.body"],
                "default_operator":"and"
              }
            }
          }
        }
      ],
      "minimum_should_match":1
    }
  },
  "from":0,
  "size":10,
  "sort":[{"created_at":{"order":"desc"}}]
}

or検索になるので、shouldの中にbodyとcomments.bodyの検索queryを書いてます。で、どれか一方に必ずヒットするようにしたいにで、「minimum_should_match」を定義してます。

nestedを使うことで階層的なデータを格納し検索するのが、楽になります。

5
6
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
5
6