我有這樣的情況:
duplicates = ['a'/span>,'b'/span>,'c'/span>,'d'/span>]
if duplicates.length >4]
Photo.includes(:tags).where('tags.name IN (?)', duplicates)
.references(:tags).limit(15).each do |f|
returned_array.push(f.id)
結束
結束。
duplicates是一個與其他Photo標簽重復的標簽陣列
我想得到的是包括duplicates陣列中所有標簽的Photo,但現在我得到的每張Photo都包括陣列中至少一個標簽。
謝謝你的回答:
我試了一下,有些東西開始作業了,但對我來說不是很清楚,需要一些時間來執行。
今天,我讓它創建陣列,對它們進行比較,取出陣列中存在超過X次的重復部分,最后得到一個照片ID的uniq陣列。
uj5u.com熱心網友回復:
在我看來,問題在于你只做了一個連接,這意味著你必須指定tags.name在重復串列中。
你可以從兩個地方來解決這個問題:
對于你的例子,查詢是這樣的:"在照片表中找到所有與標簽表中的特定記錄集有關系的記錄"。因此,我們需要將照片表連接到標簽表,并指定我們連接的唯一標簽為重復串列中的標簽。
我們可以使用一個行內來實作這個目的
。 select photos.* from photos
內部 join 標簽 as d1 on d1.name = 'a' and d1.photo= photos.id
內部 join 標簽 as d2 on d2.name = 'b' and d2.photo= photos.id
內部 join 標簽 as d3 on d3.name = 'c' and d3.photo= photos.id
內部 join 標簽 as d4 on d4.name = 'd' and d4.photo= photos.id
在ActiveRecord中,我們似乎不能為連接指定別名,但我們可以連鎖查詢,所以我們可以這樣做:
query = Photo
duplicate.each_with_index do |tag, index|
join_name = "d#{index}"。
query = query.joins("inner join tags as #{join_name} on #{join_name}. name = '#{tag}' and #{join_name}.photo_id = photos.id"/span>)
end。
很難看,但能完成作業。我確信會有一個更好的方法,使用arel來代替 - 但它演示了如何構建一個SQL查詢來找到所有與所有重復標記有關系的照片。
另一種方法是將你所擁有的東西在應用程式中進行過濾。由于您已經擁有至少有一個標簽的照片,您可以直接選擇那些擁有所有標簽的照片。
Photo
.includes(:tags)
.joins(:tags)
.where('tags.name IN (?)', duplicates)
.select do |photo|
( duplicates - photo.tags.map(&:name)) .empty?
結束。
(diplicates - photo.tags.map(&:name)).empty?獲取diplicates陣列并洗掉所有出現在照片標簽中的任何專案。如果這回傳一個空陣列,那么我們知道照片中的標簽也有所有重復的標簽。
如果重復陣列很大,這可能會產生性能問題,因為它有可能回傳資料庫中的所有照片。
uj5u.com熱心網友回復:
如果你想找到擁有所有給定標簽的照片,你只需要應用一個GROUP,并使用HAVING在該組上設定一個條件:
class Photo>
def self.with_tags(*names)
t = Tag.arel_table
joins(:tags)
.where(tags: { name: names })
.group(:id)
.have(t[:id].count.eq(tags.length)) # COUNT(tags.id) = ?
end。
end end
這有點像一個WHERE子句,但它適用于組。使用.gtq(>=)而不是.eq將得到可以擁有串列中所有標簽的記錄,但可能擁有更多的標簽。
解決這個問題的一個更好的方法是使用一個更好的領域模型,首先不允許有重復的記錄:
。
class Photo < ApplicationRecord
has_many :taggings[/span]。
has_many :tag, through: :taggings.
結束
class Tag < ApplicationRecord
has_many :標簽
has_many :photos, through: :taggings.
驗證了:name。
唯一性: true。
resenece: true, resenece:
結束
class Tagging < ApplicationRecord
belongs_to :Photo
belongs_to :標簽
驗證了:tag_id。
唯一性: { 范圍: :photo_id }
end
通過在tags.name上添加唯一索引和在taggings.tag_id和taggings.photo_id上添加復合索引,就不會產生重復。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/307024.html
標籤:
