我只是从Tire gem转移到官方的elasticsearch
Ruby wrapper,我正在努力实现更好的搜索功能.
我有一个模型InventoryItem和一个模型商店.商店has_many:inventory_items.我在Store上有一个名为local的模型范围
scope :local,lambda{|user| near([user.latitude,user.longitude],user.distance_preference,:order => :distance)}
我希望搜索只返回此范围的结果,所以我尝试了:InventoryItem.local(user).search ….但它搜索整个索引,而不是范围.在做了一些研究之后,看起来过滤器是实现这一目标的好方法,但我不确定如何实现.我也愿意采用其他方式实现这一目标.我的最终目标是能够根据商店位置搜索InventoryItem模型的子集.
解决方法
您可以做的另一件事是将有效ID列表发送到弹性,因此它将自己过滤掉记录,然后对剩下的记录执行搜索.我们没有测试它是否更快,但我认为应该,因为弹性是一个搜索引擎.
def search # retrieve ids you want to perform search within @store_ids = Store.local(current_user).select(:id).pluck(:id) # you Could also check whether there are any ids available # if there is none - no need to request elastic to search @response = InventoryItem.search_by_store_ids('whatever',@store_ids) end
一个模型:
class InventoryItem # ... # search elastic only for passed store ids def self.search_by_store_ids(query,store_ids,options = {}) # use method below # also you can use it separately when you don't need any id filtering self.search_all(query,options.deep_merge({ query: { filtered: { filter: { terms: { store_id: store_ids } } } } })) end # search elastic for all inventory items def self.search_all(query,options = {}) self.__elasticsearch__.search( { query: { filtered: { query: { # use your fields you want to search,our's was 'text' match: { text: query },},filter: {},strategy: 'leap_frog_filter_first' # do the filter first } } }.deep_merge(options) # merge options from self.search_by_store_ids if calling from there # so the ids filter will be applied ) end # ... end
这样你也必须索引store_id.
您可以阅读有关过滤器here的更多信息.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。