幾天後,我想出瞭解決方案!下面是我所做的:
這是我用或想鏈一起查詢:
people = People.where(status: status_approved).fuzzy_search(first_name: "Test").where("last_name LIKE ?", "Test")
至於晃藩建議,當你在控制檯看,這將產生以下SQL:
SELECT "people".*, COALESCE(similarity("people"."first_name", 'test'), 0) AS "rank69146689305952314"
FROM "people"
WHERE "people"."status" = 1 AND (("people"."first_name" % 'Test')) AND (last_name LIKE 'Test') ORDER BY "rank69146689305952314" DESC
然後,我挖掘到了這個文本寶石,並發現了排名是如何產生的。我在textacular.rb文件中找到它,然後使用它製作了SQL查詢。我也換成了「AND」所連接的最後兩個條件與「OR」:
# Generate a random number for the ordering
rank = rand(100000000000000000).to_s
# Create the SQL query
sql_query = "SELECT people.*, COALESCE(similarity(people.first_name, :query), 0)" +
" AS rank#{rank} FROM people" +
" WHERE (people.status = :status AND" +
" ((people.first_name % :query) OR (last_name LIKE :query_like)))" +
" ORDER BY rank#{rank} DESC"
我指的表和字段,因爲這是給我的錯誤信息時,拿出所有引號中的SQL查詢當我把它們留在那裏,即使我用單引號。
然後,我使用find_by_sql方法來檢索數組中的對象標識People
。符號(:status
,:query
,:query_like
)用於防止SQL注入,所以相應地設置其值:
# Retrieve all the IDs of People who are approved and whose first name and last name match the search query.
# The IDs are sorted in order of most relevant to the search query.
people_ids = People.find_by_sql([sql_query, query: "Test", query_like: "%Test%", status: 1]).map(&:id)
我得到在陣列中的ID而不是People
對象,因爲find_by_sql
返回Array
對象和而不是通常返回的CollectionProxy
對象,所以我無法在此陣列上使用ActiveRecord查詢方法,如where
。使用這些ID,我們可以執行另一個查詢來得到一個CollectionProxy
對象。但是,有一個問題:如果我們只是簡單地運行People.where(id: people_ids)
,那麼ID的順序將不會被保留,所以我們所做的所有相關性排名都沒有。
幸運的是,有一個很好的名爲order_as_specified的寶石,可以讓我們按ID的特定順序檢索所有People
對象。雖然寶石會起作用,但我並沒有使用它,而是編寫了一小段代碼來製作可以保持順序的條件。
order_by = people_ids.map { |id| "people.id='#{id}' DESC" }.join(", ")
如果我們people_ids
陣列是[1, 12, 3]
,它會創建下列順序聲明:
"people.id='1' DESC, people.id='12' DESC, people.id='3' DESC"
我從this comment,以這種方式書面命令語句將維持秩序的教訓。
現在,剩下的就是從ActiveRecord中檢索People
對象,確保指定順序。
people = People.where(id: people_ids).order(order_by)
而且做到了!我不擔心刪除任何重複的ID,因爲ActiveRecord在您運行where
命令時會自動執行該操作。
據我所知,這段代碼不是非常便於攜帶,如果修改了people
表的列中的任何一列,它將需要一些更改,但它完美地工作,似乎根據控制檯只執行一個查詢。
[以下信息可能與您的問題有關](http://stackoverflow.com/q/31096009/3444240) – potashin