我只是从Tire gem转移到官方弹性搜索Ruby wrapper,我正在努力实现更好的搜索功能。
我有一个模型InventoryItem
和一个模型Store
。 Store
has_many :inventory_items
。我在商店中有一个名为local
scope :local, lambda{|user| near([user.latitude, user.longitude], user.distance_preference, :order => :distance)}
我希望搜索只返回此范围的结果,所以我尝试了:InventoryItem.local(user).search....
但它搜索整个索引,而不是范围。在做了一些研究后,看起来过滤器是实现这一目标的好方法,但我不确定如何实现。我也愿意采用其他方式实现这一目标。我的最终目标是能够根据商店位置搜索InventoryItem
模型的子集。
答案 0 :(得分:6)
您可以做的另一件事是将有效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。
答案 1 :(得分:0)
我会留下这个答案而不接受,直到赏金结束 - 如果您认为自己找到了更好的解决方案,请随意添加答案。
经过一番挖掘后,答案才变得相当简单。
使用命名范围:
scope :for_stores, lambda{ |stores| where(store_id: stores.map(&:id)) }
我的控制器方法:
def search
@stores = Store.local(current_user) # get local stores
response = InventoryItem.search 'whatever' # execute the search
@inventory_items = response.records.for_stores(@stores) # call records
end
在弹性搜索回复中,您可以拨打records
或results
。仅调用results
只会产生您可以显示的索引的结果等。调用records
实际上会拉出AR记录,这样您就可以像上面那样链接方法。凉!显然,docs中有更多信息。