簡體   English   中英

按標簽進行獨家過濾

[英]Exclusive filtering by tag

我正在使用Rails 3.0和MySql 5.1

我有以下三種模型:

問題,標簽和QuestionTag。

標記具有稱為名稱的列。

問題通過QuestionTags具有許多標簽,反之亦然。

假設我有n個標簽名。 如何查找具有全部 n個標簽的問題,這些問題由標簽名稱標識。

以及如何在單個查詢中做到這一點。

(如果您可以說服我,在多個查詢中執行此操作是最佳選擇,那么我會接受的)

純Rails 3解決方案將是首選,但是我也不反對純SQL解決方案。

請注意,難點在於進行查詢時不會給出所有帶有任何標簽的問題,而是僅給出帶有所有標簽的問題。

這是我為自己找到的解決方案。 未經修改,它將僅在Rails 3(或更高版本)中工作。

在標記模型中:

scope :find_by_names, lambda { |names| 
  unless names.empty?
    where("tags.name IN (#{Array.new(names.length, "?").join(",")})", *names) 
  else
    where("false")
  end
}  

在問題模型中:

scope :tagged_with, lambda { |tag_names| 
  unless tag_names.blank?
    joins(:question_tags).
    where("questions.id = question_tags.question_id").
    joins(:tags).where("tags.id = question_tags.tag_id").
    group("questions.id").
    having("count(questions.id) = ?", tag_names.count) & Tag.find_by_names(tag_names) 
  else
    scoped
  end
}

& Tag.find_by_names(tag_names)結合了兩個范圍,使得tags上的& Tag.find_by_names(tag_names)實際上是作用域模型上的聯接。

[更新]

我的sql-fu有所改進,所以我想我也將提供一個純SQL解決方案:

SELECT q.*
FROM (
SELECT DISTINCT q.*
FROM `questions` q
JOIN question_tags qt
ON qt.question_id = q.id
JOIN tags t
ON t.id = qt.tag_id
WHERE t.name = 'dogs'
) AS q
JOIN question_tags qt
ON qt.question_id = q.id
JOIN tags t
ON t.id = qt.tag_id
WHERE t.name = 'cats'

這將查找所有已用“貓”和“狗”標記的問題。 這個想法是為我要過濾的每個標簽創建一個嵌套子查詢。

還有其他幾種方法。 我不確定將子查詢放在FROM子句中而不是WHERE子句是否有所不同。 任何見識將不勝感激。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM