简体   繁体   English

使用布尔块过滤(Tire / ElasticSearch)

[英]Filter with boolean block (Tire / ElasticSearch)

I have this search feature that has a text/keyword box and a bunch of filters; 我有这个搜索功能,有一个文本/关键字框和一堆过滤器; I have it implemented right now with the following structure: 我现在使用以下结构实现它:

query do
  boolean do
    must { string params[:text], default_operator: "AND" } unless params[:text].blank? 
    must { }   unless 
    must { }   unless 
    should { } unless
    # some more must / should / must_not queries
  end
end

# Some sorting

As far as I have read, it would be a better approach to implement it using the actual filter provided by tire (in terms of speed and cacheing). 据我所知,使用轮胎提供的实际filter (在速度和缓存方面)实现它将是更好的方法。

I want to ask what would be the right way of implementing this? 我想问一下实现这个的正确方法是什么? I couldn't find a way of passing a similar boolean block to a filter ... That would be nice. 我找不到将类似的boolean块传递给filter ......这样会很好。 Maybe I am doing it wrong? 也许我做错了?

I am thinking of doing something like 我在想做类似的事情

# This would be the main query, by text/keyword
query { string params[:text], default_operator: "AND" } unless params[:text].blank? 

filter do
  boolean do
    # My regular filters that I implemented with queries
    must { }   unless 
    must { }   unless 
    should { } unless
  end
end

# Some sorting

This gives me the following error (at the filter block line): ArgumentError - wrong number of arguments (0 for 1): 这给了我以下错误(在filter块行): ArgumentError - wrong number of arguments (0 for 1):

Also, I know that this behavior can be achieved using ElasticSearch JSON queries, as shown here: http://www.elasticsearch.org/guide/reference/query-dsl/bool-filter/ . 此外,我知道使用ElasticSearch JSON查询可以实现此行为,如下所示: http ://www.elasticsearch.org/guide/reference/query-dsl/bool-filter/。 So I assume tire provides a similar functionality on top of this feature. 所以我假设轮胎在此功能的基础上提供了类似的功能。

Thank you for your help. 谢谢您的帮助。

EDIT 编辑
What I am trying to do now is to use a filtered search, in the following way: 我现在要做的是使用过滤搜索,方法如下:

query do
  filtered do
    query { string params[:text], default_operator: "AND" } unless params[:text].blank?

    # And here I would like to add the filter block... but for now I am using the filter :and
    filter :and, { :terms => { } } unless params[:something1].blank?, 
                 { :terms => { } } unless params[:something2].blank?,
                 { :range => { } } unless params[:something3].blank?,
                 # more filters that need the AND behavior
    filter :or, { :terms => { } } unless params[:something4].blank?
                 # more filters that need the OR behavior
  end
end

I am thinking of this approach because I also read that a filter :and is faster than a boolean one. 我正在考虑这种方法,因为我也读过一个filter :and boolean Is this correct? 这个对吗?

Now, will these filters still get cached? 现在,这些过滤器是否仍会被缓存? Also, is this the right approach in this situation? 另外,在这种情况下,这是正确的方法吗?

Thank you! 谢谢!

EDIT 编辑

From what I've read in the issue posted in the comments, I think I could do something like: 从我在评论中发布的问题中读到的内容,我想我可以做类似的事情:

filter :bool => [
  { :must => { :terms => { } } } unless ... ,
  { :must => { :terms => { } } } unless ... ,
  { :should => { :terms => { } } } unless ... ,
  # and the other filters

] ]

Is this right? 这是正确的吗?

Thanks! 谢谢!

I just found the following issue https://github.com/karmi/tire/issues/2 . 我刚刚发现以下问题https://github.com/karmi/tire/issues/2 Seems like karmi did not really implement this feature for filter? 好像karmi没有真正实现过滤器的这个功能?

Meanwhile, as I saw in some of the integration tests, I think I can do something like this: 同时,正如我在一些集成测试中看到的那样,我想我可以这样做:

filter :bool => [
  { :must => { :terms => { } } } unless ... ,
  { :must => { :terms => { } } } unless ... ,
  { :should => { :terms => { } } } unless ... ,
  # and the other filters
]

Here is the source: https://github.com/karmi/tire/commit/01ba026 以下是来源: https//github.com/karmi/tire/commit/01ba026

Also, I ended up writing simple, single filters for my particular case: 另外,我最终为我的特定情况编写了简单的单个过滤器:

query { all } unless !params[:keyword].blank?
query { string params[:keyword], default_operator: "AND" } unless params[:keyword].blank?

filter :term, :a => params[:a] unless params[:a].blank?
filter :term, :b => params[:b] unless params[:b].blank?

filter :range, :c => { gte: params[:c_min] } unless params[:c_min].blank?
filter :range, :c => { lte: params[:c_max] } unless params[:c_max].blank?

filter :terms, :d => params[:d] unless params[:d].blank?

# and more such filters, just wanted to give more examples since 
# the documentation is so sparse over the internet and I know what 
# it takes to find everything in one place :)

I still think this is not the most convenient approach but it does the job in my case (a boolean block would be nice to have, for filter, but as far as I've read, an :and filter is faster than a :bool one - and listing a bunch of filters, as I did above, as far as I understood so far, creates such an :and filter). 我仍然认为这不是最方便的方法,但它在我的情况下完成了工作(对于过滤器来说,布尔块很好,但据我所知,a :and filter比a :bool更快)一个 - 并列出了一堆过滤器,就像我上面所做的那样,据我所知,到目前为止,创建了这样一个:and过滤器)。

I think this is a better approach than the initial one, of having only queries, since now these filters could be cached (as far as I read, again). 我认为这是一个比初始方法更好的方法,只有查询,因为现在这些过滤器可以被缓存(据我所读,再次)。

Hope this would help someone in the future :) 希望这将有助于未来的人:)

Also, if anyone has a better suggestion / explanation / helpful tip, please feel free to contribute! 此外,如果有人有更好的建议/解释/有用的提示,请随时贡献!

Thanks! 谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM