3

Mongoid で Tire を使用していますが、ElasticSearch でイベントを検索するためのクエリを構築する方法がわかりません。特に、ユーザーがフォローしているパフォーマーのイベントに加えて、ユーザーが見ているイベントを見つけようとしています。

# app/models/event.rb
class Event
  include Mongoid::Document
  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :name, type: String

  has_and_belongs_to_many :performers
  has_many :watchers, class_name: 'User'

  mapping do
    indexes :name
    indexes :watcher_ids, type: 'string', index: :not_analyzed
    indexes :performer_ids, type: 'string', index: :not_analyzed
  end
end

次のクエリは、ウォッチャーまたはパフォーマーのいずれかに対してのみ機能します。

Tire.search 'events' do
  query do
    string params[:query]
    # Only one of these will work at a time:
    terms :performer_ids, current_user.followed_performers.collect(&:id).map(&:to_s)
    terms :watcher_ids, [current_user.id.to_s]
  end
end
  • 私の例を間違って入力したため、小さな編集。

これは「機能している」ように見える解決策です...しかし、間違っていると感じます

Tire.search('events') do
  query do
    boolean do
      should { string params[:query] }
      should { string "performer_ids:#{current_user.followed_performers.collect(&:id).map(&:to_s).join(',')}" }
      should { string "watcher_ids:#{current_user.id.to_s}" }
    end
  end
end
4

2 に答える 2

4

あなたは正しい道を進んでいますが、Russ Smith のアドバイスに従って、filterDSL を使用する必要があります。

ここで、 を繰り返し呼び出すとfilter、union: が実行されますAND。ユーザーが見ているイベントまたはユーザーがフォローしているパフォーマーのイベントを返したい場合or、フィルターを使用する必要があります。

また、最高のパフォーマンスを得るにfilteredは、最上位のフィルターではなく、クエリを使用します。前者の場合、フィルターが最初に実行され、コーパスがスライスされ、このサブセットに対してのみクエリが実行されます。

コードは次のようになります。

Tire.search 'events' do
  query do
    filtered do
      query do
        string params[:query]
      end
      filter :or, terms: { organization_ids: current_user.followed_performers.collect(&:id).map(&:to_s) },
                  terms: { watcher_ids:      [current_user.id.to_s] }
    end
  end
end

その他の例については、統合テストを参照してください。

于 2012-12-22T09:52:48.430 に答える
2

あなたが探しているのはフィルターだと思います。これは完全にテストされたコードではありませんが、正しい方向に導く可能性があります。

class Event
  include Mongoid::Document
  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :name, type: String

  has_and_belongs_to_many :performers
  has_many :watchers, class_name: 'User'

  mapping do
    indexes :name
    indexes :watcher_ids, type: 'integer', index: :not_analyzed
    indexes :performer_ids, type: 'integer', index: :not_analyzed
  end
end

Tire.search('events') do
  query do
    string 'my event'
  end

  filter :in, :organization_ids, [1,2,3]
  filter :in, :watcher_ids, [1]
end
于 2012-12-22T01:04:04.060 に答える