[017] 通过Ruby Elasticsearch 7.14进行文档搜索并显示相应结果和匹配数量

[017] 使用 Ruby elasticsearch 7.14 进行文档搜索并显示相关结果与数量。

总结

使用Ruby的Elasticsearch客户端在Elasticsearch 7.14中操作REST API。
此外,为了进行比较,还将说明使用Kibana DevTool的查询。

本次的任务是通过索引“shakespeare”,进行下列操作:搜索文档并显示相应数量。

提取满足以下两个条件的文档,并显示数量。

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

但是,在这种情况下,我们也只会获取 Elasticsearch 的默认行为,仅限于获取10条。

检验环境

使用Elasticsearch + Kibana (7.14),已注册验证数据”Shakespeare”。

[00] 用 Ruby 的 Elasticsearch 客户端包操作 Elasticsearch 7.14 进行测试环境的建立篇。

参考信息

实践

如果使用Kibana DevTool的情况下

代码

使用聚合功能对名为“agg”的搜索结果进行计算。
下面的“docs_aggs”可以是任意名称。
下面“field”中的“text_entry”是字段名。

GET shakespeare/_search
{
  "query": {
    "query_string": { 
      "query": "text_entry:ACT AND text_entry:V"
    }
  },
  "aggs": {
    "docs_aggs": {
      "terms": {
        "field": "text_entry.keyword",
        "size": 2560
      }
    }
  }
}

结果

image.png

在Ruby中

代码 (Mandarin: mǎ)

最重要的部分是「如果__FILE__ == $0」之后。

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"
      }
    },
    "aggs": {
      "docs_aggs": {
        "terms": {
          "field": "text_entry.keyword",
          "size": 2560
        }
      }
    }
  }
  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}}}}}}}

答案

从以下的?中,显示了36个条目。


       {"type"=>"act",
        "line_id"=>24007,
        "play_name"=>"A Comedy of Errors",
        "speech_number"=>87,
        "line_number"=>"",
        "speaker"=>"OF SYRACUSE",
        "text_entry"=>"ACT V"}},
     {"_index"=>"shakespeare",
      "_type"=>"_doc",
      "_id"=>"27743",
      "_score"=>18.431282,
      "_source"=>
       {"type"=>"act",
        "line_id"=>27744,
        "play_name"=>"Coriolanus",
        "speech_number"=>7,
        "line_number"=>"",
        "speaker"=>"AUFIDIUS",
        "text_entry"=>"ACT V"}},
     {"_index"=>"shakespeare",
      "_type"=>"_doc",
      "_id"=>"31443",
      "_score"=>18.431282,
      "_source"=>
       {"type"=>"act",
        "line_id"=>31444,
        "play_name"=>"Cymbeline",
        "speech_number"=>13,
        "line_number"=>"",
        "speaker"=>"BELARIUS",
        "text_entry"=>"ACT V"}}]},
 "aggregations"=>
  {"docs_aggs"=>
    {"doc_count_error_upper_bound"=>0,
     "sum_other_doc_count"=>0,
     "buckets"=>[{"key"=>"ACT V", "doc_count"=>36?}]}}}

验证

DevTool 和 Ruby 的结果是否相同?

一致的情况好像相同。

image.png
广告
将在 10 秒后关闭
bannerAds