2012-01-26 71 views
1

我試圖用輪胎重寫查詢。用輪胎重寫SQL查詢

這是我的模型:

class User < ActiveRecord::Base 
    has_many :bookmarks, :dependent => :destroy 
    has_many :followed_venues, :through => :bookmarks, :source => :bookmarkable, :source_type => 'Venue' 
end 

用戶可以按照場地。而且我需要搜索某些用戶跟隨的場所。

到目前爲止,我一直在用ActiveRecord做:

@user.followed_venues.where(["venues.title LIKE ?", "%"+params[:q]+"%"]) 

這顯然是不理想的,所以我加了elasticsearch我用輪胎的應用程序。

我會如何搜索帶輪胎的場地,並按照用戶進行過濾?

回答

1

我打算髮佈一個答案來回答我自己的問題。

因此,搜索場地很容易。標準Venue.tire.search {...}問題是如何按照用戶過濾場地。我沒有使用Venue模型進行搜索,而是決定索引書籤。

這是我的書籤模型

class Bookmark < ActiveRecord::Base 
    belongs_to :bookmarkable, :polymorphic => true 

    def to_indexed_json 
    { 
     :title => bookmarkable.display_name, 
     :user_id => user_id 
    }.to_json 
    end 
end 

在此之後我有USER_ID和索引場地名稱。現在搜索變得如此簡單:

Bookmark.tire.search :load => {:include => 'bookmarkable'}, :page => page, :per_page => per_page do 
    query do 
    fuzzy :title => { :value => query.downcase, :min_similarity => 0.6, :prefix_length => 2} 
    end 
    filter :terms, {:bookmarkable_type => ["Venue"], :user_id => [user.id]} 
end 

現在這不是一個完整的解決方案。我希望我甚至可以正確使用filter :terms。我現在回來的結果實際上是一系列書籤。但是很容易爲它們加載實際場地,也可能將它包裝在WillPaginate集合中,以便在前端進行更好的分頁。

此解決方案的任何問題?它與phoet建議將用戶ID添加到場地索引時相比如何?

+0

解決方案的問題在於,在查詢中使用'load'命令打擊數據庫。這當然不如僅使用elasticsearch索引那麼快。 – tommasop

+0

是的,我明白這一點。但我需要AR對象,所以沒有辦法。 – egze

+0

模糊方法不存在。這段代碼不起作用,對吧? –

0

我會爲每個場地創建一個文檔,然後添加一個包含所有用戶id的數組的字段。

你真的確定,這對於elasticsearch來說是一個適當的任務嗎?

我想只是在索引中搜索場地名稱,然後在關係數據庫中查找需要的數據會更容易。

+0

我認爲這是一個彈性搜索的任務,因爲我也想有場地名稱的模糊匹配。我正在嘗試另一種方法如何去做。我將索引具有user_id的書籤併爲索引添加場所名稱,而不是索引場所。我將在一秒內發佈解決方案。 – egze

+0

@phoet是的,我認爲在elasticsearch查詢本身中最好使用'filter',因爲數據庫查詢非常簡單/快速。顯然,一個缺點是你需要保持數據庫和索引同步,所以記錄不會在用戶之間混合。 – karmi