狂欢:分类之间的交集

时间:2014-04-01 15:19:22

标签: ruby-on-rails ruby e-commerce spree taxonomy

是否可以查询属于多个分类单元的产品?就像一个数学交集。

例如:我出售属于分类大学的书籍> ASU,属于分类课程>工程

我希望能够查询属于ASU Engineering路径的所有书籍。 像

这样的东西
Spree::Product.in_taxon(asu_taxon).in_taxon(eng_taxon)

3 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。我将使用spree沙盒数据,因此如果您感兴趣,可以尝试使用结果。

首先,我们可以遍历所有产品,并使用纯Ruby检查他们的分类:

Spree::Product.all.select do |product|
  taxon_names = product.taxons.map(&:name)  
  taxon_names.include?("Rails") && taxon_names.include?("Bags")  
end

这样做的缺点是它必须从数据库中检索所有产品,然后在单独的查询中检索所有产品。如果你有相当数量的产品,它会很慢。

我们可以通过以下方式改善:

Spree::Product.joins(:taxons).includes(:taxons).where(spree_taxons: { name: ["Rails", "Bags"]}).all.select do |product|
  taxon_names = product.taxons.map(&:name)  
  taxon_names.include?("Rails") && taxon_names.include?("Bags")  
end

这将只获得属于两个分类中的一个的产品,并使用单个查询检索所有分类单元数据。它会快得多,但我们可以做得更好......有点......

您可以使用SQL连接多次连接表,以便将其减少为一个查询,以检索您想要的所有记录:

Spree::Product
  .joins('INNER JOIN spree_products_taxons rails_join ON (spree_products.id = rails_join.product_id)')
  .joins('INNER JOIN spree_taxons rails_taxon ON (rails_join.taxon_id = rails_taxon.id AND rails_taxon.name == "Rails")')
  .joins('INNER JOIN spree_products_taxons bags_join ON (spree_products.id = bags_join.product_id)')
  .joins('INNER JOIN spree_taxons bags_taxon ON (bags_join.taxon_id = bags_taxon.id AND bags_taxon.name == "Bags")')

这有点难看,但这是获取数据的最快方式,因为只使用单个SQL查询就可以获得所需的产品。

可能没有那么糟糕的方法,但这是我所拥有的最好的方法!

答案 1 :(得分:0)

您可以尝试Spree::Product.joins('INNER JOIN spree_products_taxons rails_join ON (spree_products.id = rails_join.product_id)').joins('INNER JOIN spree_taxons rails_taxon ON (rails_join.taxon_id = rails_taxon.id AND rails_taxon.name NOT IN ("Hide", "Old") )')

答案 2 :(得分:0)

我有相同的用例,最终做到了这一点:

Product.joins(:classifications)
  .where(classifications: {taxon_id: taxon_ids})
  .group('products.id')
  .having('COUNT("products"."id") = ?', taxon_ids.count)

希望有所帮助