首先Solr是什么,簡(jiǎn)單來(lái)說(shuō)就是一個(gè)單獨(dú)的搜索項(xiàng)目,能夠加快搜索速度的api項(xiàng)目,存的數(shù)據(jù)由本地?cái)?shù)據(jù)庫(kù)的數(shù)據(jù)經(jīng)過(guò)項(xiàng)目做一定處理保存上去证逻,然后搜索通過(guò)http傳參的模式,返回所需數(shù)據(jù)類型的結(jié)果(json,xml等)抗斤,下面是百度百科解釋:
Solr是一個(gè)獨(dú)立的企業(yè)級(jí)搜索應(yīng)用服務(wù)器囚企,它對(duì)外提供類似于Web-service的API接口。用戶可以通過(guò)http請(qǐng)求豪治,向搜索引擎服務(wù)器提交一定格式的XML文件洞拨,生成索引扯罐;也可以通過(guò)Http Get操作提出查找請(qǐng)求负拟,并得到XML格式的返回結(jié)果。
本來(lái)直接裝的sunspot_solr的gem包歹河,但是后來(lái)不知道為什么連接不上掩浙,就換成外部的直接跑的Tomcat+solr服務(wù)的模式了花吟,具體服務(wù)配置和安裝就不多說(shuō)了,說(shuō)一下使用吧
1.建立索引:在model里面設(shè)定好需要搜索的字段名和類型,需要注意的是每次只能搜索一個(gè)模型厨姚,索引也是一條記錄一條記錄的建立的衅澈,不能進(jìn)行像數(shù)據(jù)庫(kù)里的鏈接查詢,所以在建立索引的時(shí)候需要給join數(shù)據(jù)配置進(jìn)去谬墙,例如
searchable do
text :title
text :content do
#html標(biāo)簽處理
Sanitize.fragment(self.content)
end
#從關(guān)聯(lián)的province處找到區(qū)域的id
integer :region_id do
province.region_id
end
integer :province_id
integer :city_id
integer :town_id
#關(guān)聯(lián)用途分類的id今布,:multiple就是數(shù)組的意思,例如某條數(shù)據(jù)的usage_category_ids是[1,2,3]
#而搜索條件給的是[3,4,5],那么這條記錄就會(huì)被檢索出來(lái)
integer :usage_category_ids, :multiple => true do
usage_categories.map(&:id)
end
time :published_at
end
在after_save里加上self.index!保證每次保存結(jié)束都可以更新索引拭抬。而對(duì)于當(dāng)前已有數(shù)據(jù)可以用
#參數(shù)意思:緩沖大小部默,模型名,不知道..
rake sunspot:reindex[batch_size,modes,silence]
rake sunspot:reindex[1000,Info]
2.搜索:
# 和Info.select(_select).includes(_includes)一樣
search = Info.solr_search(select: _select ,include: _includes) do
#全文搜索:指定搜索區(qū)域title,content
fulltext params[:kw],fields:[:title,:content]
#any do 包圍起來(lái)的相當(dāng)于 and (region_id=? or province_id=? or city_id not in(1,2,3))
any do
with :region_id ,subscription["region"] unless subscription["region"].blank?
with :province_id ,subscription["province"] unless subscription["province"].blank?
without :stage_id , [1,2,3]
end
# published_at>=? published_at <=?
#對(duì)應(yīng)大于和小于是:greater_than 和less_than
with(:published_at).greater_than_or_equal_to p[:published_at_gteq]
with(:published_at).less_than_or_equal_to p[:published_at_lteq]
#分頁(yè)數(shù)據(jù)造虎,可適用于自帶的分頁(yè)方法
paginate page: p[:page]||1, per_page: p[:per_page]||20
#排序
order_by 'published_at' ,:desc
end
@infos = search.results
log中sql為:SELECT id, title, province_id, city_id, town_id, content FROM
infos
WHEREinfos
.id
IN (5, 111, 11, 8, 10, 7, 9, 12, 6, 14, 17, 20, 13, 16, 19, 15, 18, 21, 23, 26)
也就是說(shuō)solr其實(shí)是根據(jù)搜索條件返回一堆id回來(lái)傅蹂,最終的select和join都是后再執(zhí)行默認(rèn)數(shù)據(jù)庫(kù)的一次查詢