2

次の構造のテーブル「リード」があります。

# == Schema Information
#
# Table name: leads
#
#  id                       :integer          not null, primary key
#  data                     :jsonb            not null
#  state                    :string
#  priority                 :string
#  lead_no                  :string
#  user_id                  :integer
#  location_place_id        :string
#  uuid                     :string
#  agent_id                 :integer
#  location_coordinates     :geography        point, 4326
#  location                 :jsonb            not null
#  user_details             :jsonb            not null
#  inventory_id             :integer
#  source_details           :jsonb            not null
#  connect_details          :jsonb            not null
#  referral_details         :jsonb            not null
#  process_details          :jsonb            not null
#  tags                     :jsonb            not null
#  created_at               :datetime
#  updated_at               :datetime
#  name                     :string

user_details jsonb 列には、データが {name : "John Doe", country : "IN", phone_no : "123456789"}の形式で格納されます。名前キーのILIKEを次のように使用してデータベース列をクエリしたい:

Lead.where("user_details->>name ILIKE ?","john%")

これを実現するために、次のように移行を作成しました。

class AddIndexUserNameOnLeads < ActiveRecord::Migration[5.2]
  def up
      execute("CREATE INDEX leads_user_details_name_idx ON leads USING gin((user_details->>'name') gin_trgm_ops)")
  end

  def down
    execute("DROP INDEX leads_user_details_name_idx")
  end
end

これにより、必要なインデックスが作成されます。以前の移行で pg_trgm 拡張機能を有効にしました。私のstructure.sqlは次のようになります: ここに画像の説明を入力

また、対応するschema.rbは次の行をリード テーブルに追加します -

t.index "((user_details ->> 'name'::text)) gin_trgm_ops", name: "leads_user_details_name_idx", using: :gin

ただし、データベースにクエリを実行しようとすると、順次スキャンが実行されます。 ここに画像の説明を入力

一方、user_details 列全体の gin インデックスを作成し、"@> {name: "john"}.to_json"を使用してクエリを実行すると、スキャンにインデックスが使用されます 。ここに画像の説明を入力

Rails のバージョンは5.2.0で、PostgreSQL のバージョンは12.5です。このユースケースでILIKEクエリを使用するにはどうすればよいですか? どこが間違っていますか?必要に応じて詳細をお知らせいたします。

4

2 に答える 2