Help us understand the problem. What is going on with this article?

RubyからCloudSearchを使う(基本)

More than 5 years have passed since last update.

(追記 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インスタンスでは作れないので、そこは残念。
u1tnk
vikona30
国内最大の審査制飲み会マッチングアプリ「JOIN US(ジョイナス)」を開発・運営するスタートアップ。
http://joinus30.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした