0

一致するオプションタグの量順に並べられた、すべての条件付きタグでタグ付けされた、できるだけ多くのオプションタグに一致する製品を見つけたいと思います。

私はオプションのタグを数えるためにこれを思いついた:

optional_tags = [1,2,3]
conditional_tags = [4]

products = Product.select('COUNT(*) AS count_all, products.*')
                  .joins(:tags).where('tags.id IN (?)', optional_tags)
                  .group('products.id')
                  .order('count_all DESC')

製品IDと一致するオプションのタグの数を正常に取得しました:

products: {30=>4, 26=>3, 29=>3, 27=>2, 28=>1}

条件付きタグを追加しようとすると、空のハッシュしか取得されません。私はそれをこのように試しました:

products = Product.where('tags.id IN (?)', conditional_tags)
                  .select('COUNT(*) AS count_all, products.*')
                  .joins(:tags).where('tags.id IN (?)', optional_tags)
                  .group('products.id')
                  .order('count_all DESC')

Railsはクエリを最適化し、すべての場所のパーツを結合します...

コンストラクトに条件付きタグを追加するにはどうすればよいですか?助けてくれてありがとう!

例:

製品の種類は重要ですが、人々は細部を気にしません。

condition_tags=[ 1 台の車]

optional_tags = [ 2 3 メルセデス4 高速]

赤い でも大丈夫ですが、一致するタグがもっとあるとしても、メルセデスの赤い高速バイク 結果のリストに含まれないはずです。

4

3 に答える 3

1

さて、私は最終的にそれを理解したと思います:

class Product < ActiveRecord::Base
  scope :having_tags, -> { |tags|
    joins(:tags).where('tags.id IN (?)', tags)
  }

  scope :ordered_by_tag_count, -> { |tags|
    joins(:tags)
    .where('tags.id IN (?)', tags)
    .group('products.id')
    .order('count_all DESC')
  }
end

これらのタグがある場合:

conditional_tags = [1 台の車]

optional_tags = [赤 2、メルセデス 3、速い 4]

あなたはこれを行うかもしれません:

Product.having_tags([1]).ordered_by_tag_count([2, 3, 4])
于 2013-02-07T21:07:18.317 に答える
0

助けてくれてありがとう、ジェイソン。私はそれを理解したと思います...オプションのタグのメインクエリ内で条件付きタグのサブクエリを実行します。

私の製品範囲:

scope :tagged, lambda { |tag_ids|
  joins(:tags)
  .where('tags.id IN (?)', tag_ids)
  .group('products.id')
}
scope :matched, lambda { |product_ids, tag_ids|
  select('COUNT(*) AS count_all, products.*')
  .joins(:tags)
  .where('products.id IN (?) AND tags.id IN (?)', product_ids, tag_ids)
  .group('products.id')
  .order('count_all DESC')
}

私のクエリ構成:

result = Product.matched(Product.tagged(branch_ids).map(&:id), tag_ids)

Rails は 2 つの別々のクエリを実行する必要があるため、パフォーマンスが少し心配です。良い点は、「メイン」クエリに .limit() を追加できることです。

1 つのクエリでこれを解決する方法を誰かが知っている場合は、お知らせください。ありがとう!

于 2013-02-08T02:54:19.503 に答える