1

Tire 允许您使用旨在镜像 JSON api 的 DSL 构建弹性搜索查询,例如:

search = Tire::Search::Search.new

search.query do
  boolean do
    should { match :title, "Red" }
    should { match :synopsis, "Red" }
    should { match :brand_title, "Red" }
  end

  boolean do
    must { term :excluded, false }
  end
end

我想把它分成我自己的 DSL 来定义可以构建的查询组,有点像 Rails 范围:

class Proxy
  def initialize
    @queries = []
  end

  def results
    search = Tire::Search::Search.new
    queries = @queries

    search.query do
      # …? What should go here to search the combined set of conditions?
    end
  end

  def term t
    query do
      boolean do
        should { match :title, t }
        should { match :synopsis, t }
        should { match :brand_title, t }
      end
    end
  end

  def included bool
    query do
      boolean do
        must { term :excluded, !bool }
      end
    end
  end

  private
  def query &block
    @queries << block
  end
end

p = Proxy.new

p.term "Red"
p.included true

p.results

问题是,轮胎不允许超过一个search.query块 - 后续querys 替换前一个。我可以使用 instance_eval 之类的东西在查询块的正确上下文中运行多个块吗?

4

3 回答 3

0

我不熟悉轮胎,但有弹性搜索查询 DSL 的经验。我认为问题在于搜索 API 只允许"query": {...}发送到_search端点的 JSON 中的一个。

这样想,如果您有多个查询,elasticsearch 将如何知道如何组合它们。您需要使用另一个bool查询来执行此操作。

是(可能很大)查询树的"query"根,你不能有多个根!

希望我能帮上忙...

于 2013-07-23T22:39:46.037 回答
0

它在文档中进行了解释。检查这里http://karmi.github.io/tire/#section-84

你可以这样称呼他们

Tire.search('articles') { query { boolean &tags_query } }

并构建您自己的 lambda。

于 2013-07-23T23:32:40.410 回答
0

事实证明,这些块只能使用 instance_eval 运行,并且它们在正确的上下文中执行:

def results
  search = Tire::Search::Search.new
  queries = @queries # Only local variables are available inside the query block below

  search.query do
    queries.each do |q|
      instance_eval(&q)
    end
  end
end

在我问这个问题之前,我几乎可以肯定我已经尝试过了,但我想我之前搞砸了。

于 2013-07-25T12:54:43.650 回答