ローイングファンのプログラミング日記

ボート競技やプログラミングについて書きます

あいまい検索 Active Record where like

データベースからデータを選び出す際は、検索ワードと完全に一致するものだけでなく、部分的に一致するものも選び出したいことが多い。
幅をもたせた検索を「あいまい検索」という。
今回はあいまい検索を試す。

目次


where like

Active Recordを使ってデータベースからオブジェクトを取りだす方法は次のWebページを参照。

Active Record クエリインターフェイス
https://railsguides.jp/active_record_querying.html

あいまい検索では=ではなくlikeを使う。
書式は次のとおり。

.where('カラム名 like ?','検索したい文字列')


カラム名 like ?orandでつなぎ、複数の条件をつけることもできる。
検索したい文字列は,でつなぐ。

orでつなぐ例

.where('カラム名 like ? or カラム名 like ?', '検索したい文字列1', '検索したい文字列2')


検索したい文字列に次の記号を含めることができる。

  • 任意の1文字に一致: _
  • 0個以上の任意の文字に一致: %
  • 指定した文字と一致: [s]
    • sにもとめる文字が入る
  • 指定文字以外の文字と一致: [^s]
    • sに除外したい文字が入る


Where likeを使ったコード

データベースは前につくったtestデータベースを使う。
ボートレース(レガッタ)の結果が入ったテーブルの中からレース結果をあいまい検索で選び出す。
where_like_test.rb

require 'active_record'
require 'dotenv/load'

ActiveRecord::Base.establish_connection(
    adapter:  ENV['myadapter'],
    host:     "",
    username: ENV['myusername'],
    password: "",
    database: ENV['mydatabase']
)

class Test < ActiveRecord::Base
end

puts "男子種目を抽出"
mens_events = Test.where('events like ?', '男子%')
mens_events.each do |mens_race|
    puts "RaceNo: #{mens_race['raceno']} #{mens_race['events']} #{mens_race['groups']} 1着 #{mens_race['crew_rank1']}"
end

puts "男子種目でかつ1着が大学クルーのレースを抽出"
collegecrews = Test.where('events like ? and crew_rank1 like ?','男子%','%大学%')
collegecrews.each do |collegecrew|
    puts "RaceNo: #{collegecrew['raceno']} #{collegecrew['events']} #{collegecrew['groups']} 1着#{collegecrew['crew_rank1']}"
end


コードの説明

  • Testクラスをつくるところまでは前の記事を参照
  • where like ?
    • 男子種目を抽出
      • 男子 + 0個以上の文字で検索
      • 見つかったレコードをeachメソッドで1行ずつとりだす
      • とりだしたレコードをputsメソッドで表示する
    • 男子種目でかつ1着が大学クルーのレースを抽出
      • 検索対象となるカラム「種目」と「1着のクルー」をandでつなぐ
      • 男子 + 0個以上の文字で検索
      • 0個以上の文字 + 大学 + 0個以上の文字で検索
      • 見つかったレコードをeachメソッドで1行ずつとりだす
      • とりだしたレコードをputsメソッドで表示する


コードを実行する

Rubyコマンドを実行する前にPostgreSQLサーバーを起動しておく。
pathオプションつきbundle installでインストールしたgemをつかうのでbundle execを頭につけてコマンドで実行する。

bundle exec ruby where_like_test.rb


実行結果

男子種目と男子種目かつ1着が大学クルーのレースだけが抽出された。

男子種目を抽出
RaceNo: 1 男子エイト 予選A組 1着 A大学
RaceNo: 2 男子エイト 予選B組 1着 D大学
RaceNo: 3 男子シングルスカル 予選A 1着 クラブ3-1
RaceNo: 6 男子エイト 決勝 1着 クラブ6-1
男子種目でかつ1着が大学クルーのレースを抽出
RaceNo: 1 男子エイト 予選A組 1着A大学
RaceNo: 2 男子エイト 予選B組 1着D大学



今回の動作確認環境
macOS 10.13.4
Ruby 2.4.4p296
ターミナル 2.8.2

Windows10 1709
Ruby 2.5.1p57 [x64-mingw32]
Windows PowerShell 5.1.16299.251

PostgreSQL 10.3
Active Record 5.2.0
Pg 1.0.0
dotenv 2.3.0