LoginSignup
22
19

More than 5 years have passed since last update.

RubyからCloudSearchを使う(基本)

Last updated at Posted at 2015-06-12

(追記 6/12) あまりにも説明無かったので全般的に加筆。コードのところはいじってないです。

基本のところ。難しい事はしないです。

参考

Amazon CloudSearch とは - Amazon CloudSearch
Module: Aws::CloudSearch — AWS SDK for Ruby V2
AWS CloudSearch を使ってみた - satococoa's blog
Amazon CloudSearchで全件対象のファセットを表示する。新着(123件)みたいなやつ。 | Developers.IO

Gem

wellbredgrapefruit/asari
StevenJL/rawscsi
などがあるらしいですが、
File: README — AWS SDK for Ruby V2
こちらの公式gemを採用。理由は以下。

  • 公式でもそんな複雑でも無い
  • 経験上、メジャーじゃない(RDBに比べれば…)プロダクト使うときに柔軟性落ちると最初は良くても後でハマる。
  • プロダクト自体が変化する可能性があるので追従してくれそう

認証

AWS SDKの普通の認証

Aws.config.update(region: "region",
                  credentials: Aws::Credentials.new("accesskey","secret"),)

indexを作る。

これはweb consoleでやったので割愛。

データを入れる

jsonは最大5MB、text-array/literal-array使うときはそれぞれ1000件制限らしいので注意。

client = Aws::CloudSearchDomain::Client.new(endpoint: "http://endpoint.xxx") # dashboardで見れる。document用の方
client.upload_documents(documents: {"hoge":"fuga"}.to_json, content_type: 'application/json') 

データを検索する

簡単!ページングとかは次項を参照。

client = Aws::CloudSearchDomain::Client.new(endpoint: "http://endpoint.xxx") # dashboardで見れる。search用の方
client.search(query: 'hoge')

全データを表示する

とりあえず突っ込んだ全データ表示したくなりますよね?地味にluceneクエリを使う方法以外見当たらなかったので特記。
データ量多くなると思うので、ページング対応。
普通にlimit/offset形式のページングもありますが、取得する件数が多い(10,000件を超えると記述)ときは速度的にこちらを推奨とのこと。(参考:Amazon CloudSearch の結果のページ分割 - Amazon CloudSearch)

cursor = 'initial' # 最初はこの文字列固定。
loop do
  page = cl.search(
    query: '*:*',
    size: 1000, # 適当
    query_parser: 'lucene',
    cursor: cursor,
  )
  cursor = page.hits.cursor
  break if page.data.hits.hit.empty?

  page.data.hits.hit.each do |data|
    p data
  end
end

結果

#<struct id="1", fields={"hoge"=>["はまやらわ"]}, exprs=nil, highlights=nil>
#<struct id="2", fields={"hoe"=>["あ"]}, exprs=nil, highlights=nil>
...

structured クエリを使う

ホントに単純なケース(webページみたいにとにかくテキスト突っ込んでid取得とか)を除けば、絞りこみ(filter_query使った方が良いですが)とかtagで完全一致にしたい…とかあるとstructuredを使う事になると思います。以下のようにspace区切りでand/or使って ()でネスト可能…という感じ。

page = search_client.search(
  query_parser: 'structured',
  query: "(or 'ほげ' hoge: 'ほげ')", # field指定しないと全てのtext fieldから検索される literalとかだとfield指定必須
)

所感

  • 設定とかは超簡単だけど、Rubyからのサンプルはあんまり無い。公式ドキュメントが頼り。
  • fieldの型変更とかで再indexすると数十分普通に待たされて急いでるとストレスフルなので、余裕が必要。
  • elasticsearchに比べるとスキーマきっちり指定しないとエラーになるので柔軟性は低い…が、elasticsearchも自分でスキーマ設定するとindex作成前にする必要があるので大差は無い。
  • elasticsearchで言う1indexしか1インスタンスでは作れないので、そこは残念。
22
19
2

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
22
19