如何使用Sunspot仅在选中的模型记录中搜索文本
解决Sunspot仅在指定模型记录中搜索的问题
我太懂你遇到的这个坑了!直接在Node.where(id: ids)的结果上调用search,Sunspot根本不会买账——它还是会对着整个模型的索引跑搜索,完全无视你前面的ActiveRecord过滤条件。给你两个实用的解决思路:
方法一:在Sunspot搜索块中直接限定ID范围(推荐)
这是最高效的方式,因为Sunspot会直接在索引层面先筛选出符合ID的记录,再执行关键词搜索,不用先查数据库再过滤。
首先确保你的Node模型的Sunspot索引里包含了id字段(如果还没加的话):
class Node < ApplicationRecord searchable do integer :id # 必须加上这个,才能用id做过滤条件 text :title, :content # 你的其他可搜索字段 end end
然后修改搜索代码:
# 直接在搜索块里同时指定关键词和ID范围 search = Node.search do keywords "query" with(:id, ids) # 这里限定只搜索指定ID的记录 end # 获取最终结果 nodes_res = search.results
方法二:先查数据库再过滤搜索结果(不推荐,效率较低)
如果因为某些原因你必须先拿到ActiveRecord集合,也可以先执行Sunspot的全局搜索,再用集合去过滤结果:
nodes_res = Node.where(id: ids) search = Node.search { keywords "query" } # 用数据库查询结果去过滤搜索结果 filtered_results = search.results & nodes_res
不过这种方法不推荐,因为会先把所有匹配关键词的记录都查出来,再和数据库集合做交集,数据量大的时候会很慢。
为什么你原来的写法没用?
nodes_res.search这种调用方式其实只是语法糖,Sunspot并没有把where(id: ids)的条件整合到搜索逻辑里——它的search方法本质上还是基于整个Node模型的索引来执行的,所以前面的数据库过滤相当于白做了。
内容的提问来源于stack exchange,提问作者andgursky
相关产品推荐
相关产品推荐

