0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[016] ドキュメントの複数フィールドを使った AND による絞り込み検索 by Ruby elasticsearch 7.14

Last updated at Posted at 2021-08-14
シリーズトップページ
https://qiita.com/robozushi10/items/2c8b6951ee342b013974

概要

Ruby の Elasticsearch Client を使って Elasticsearch 7.14 で REST API の操作する.
また、比較のために、Kibana DevTool でのクエリも合せて記しておく.

今回はインデックス「shakespeare」から次の「ドキュメントの検索」を行う.

以下3つを全て満たすドキュメントを抽出する.

・フィルード「text_entry」の値に「ACT」という単語を含む
・フィルード「text_entry」の値に「V」という単語を含む
・フィルード「play_name」の値に「Cymbeline」という単語を含む

ただし、ここでも Elasticsearch デフォルト挙動の 10件しか取り出さないものとする.

検証環境

下記の要領で検証用データ「Shakespeare」が登録された
・Elasticsearch + Kibana (7.14)
を使用した

[00] Ruby の elasticsearch client パッケージを使って Elasticsearch 7.14 を操作してみる ... 検証環境構築編

参考にした情報

URL
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html

実践

Kibana DevTool の場合

コード

GET shakespeare/_search
{
  "query": {
    "query_string": {
      "query": "text_entry:ACT AND text_entry:V AND play_name:Cymbeline"
    }
  }
}

結果

image.png

Ruby の場合

コード

重要な部分は「if __FILE__ == $0 以降」である.

class MySimpleClient は丸々コピーで良い. (が、192.168.10.115 のみ、適宜読み替えること)


#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require 'multi_json'
require 'faraday'
require 'elasticsearch/api'
require 'active_support/core_ext' #! note_0004
require 'active_support' #! note_0005
 
class MySimpleClient
# note_0001
  include Elasticsearch::API
  CONNECTION = ::Faraday::Connection.new url: 'http://192.168.10.115:29200'
  def perform_request(method, path, params, body, headers = nil)
    #! note_0003
    CONNECTION.run_request \
      method.downcase.to_sym,
      path_with_params(path, params),
      (body ? MultiJson.dump(body): nil),
      {'Content-Type' => 'application/json'}
  end
 
  private
 
  def path_with_params(path, params)
    return path if params.blank?
 
    case params
    when String
      "#{path}?#{params}"
    when Hash
      "#{path}?#{params.to_query}"
    else
      raise ArgumentError, "Cannot parse params: '#{params}'"
    end
  end
end
 
if __FILE__ == $0
 
  client = MySimpleClient.new
 
  q = {
    "query": {
      # note_0006
      "query_string": { 
        "query": "text_entry:ACT AND text_entry:V AND play_name:Cymbeline"
      }
    }
  }
  res = client.search index: 'shakespeare', body: q
  h = JSON.parse(res)
  pp h
end
 
 
# note_0001: https://rubydoc.info/gems/elasticsearch-api
# note_0002: https://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Cluster/Actions#health-instance_method
# note_0003: client.cluster.health から呼び出されるので実装が必要である
# note_0004: 'active_support' を 'active_support/core_ext' に変更する.
#            APIドキュメントにある 'active_support' 指定だと次のエラーが発生してしまうためである.
#            tutorial.rb:26:in `path_with_params': undefined method `blank?' for {}:Hash (NoMethodError)
# note_0005: require 'active_support' が存在しないと次のエラーが発生してしまう.
#            /usr/local/bundle/gems/activesupport-6.0.4/lib/active_support/core_ext/object/json.rb:42:
#              in `to_json': uninitialized constant ActiveSupport::JSON (NameError)
# note_0006: mapping は次の通り
# {"shakespeare"=>
#   {"mappings"=>
#     {"properties"=>
#       {"line_id"=>{"type"=>"long"},
#        "line_number"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}},
#        "play_name"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}},
#        "speaker"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}},
#        "speech_number"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}},
#        "text_entry"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}},
#        "type"=>
#         {"type"=>"text",
#          "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}}}}}}

結果

{"took"=>1,
 "timed_out"=>false,
 "_shards"=>{"total"=>1, "successful"=>1, "skipped"=>0, "failed"=>0},
 "hits"=>
  {"total"=>{"value"=>1, "relation"=>"eq"},
   "max_score"=>22.896843,
   "hits"=>
    [{"_index"=>"shakespeare",
      "_type"=>"_doc",
      "_id"=>"31443",
      "_score"=>22.896843,
      "_source"=>
       {"type"=>"act",
        "line_id"=>31444,
        "play_name"=>"Cymbeline",
        "speech_number"=>13,
        "line_number"=>"",
        "speaker"=>"BELARIUS",
        "text_entry"=>"ACT V"}}]}}

検証

結果比較 DevTool vs Ruby が一致しているか?

🆗一致している模様

image.png

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?