2013-07-23 7 views
1

타이어는 JSON API를 반영하기 위해 설계된 DSL을 사용하여 elasticsearch 쿼리를 구축 할 수 있도록 여러 루비 블록에서 타이어 쿼리를 구성 :예를 들어,

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 종류의 레일 범위와 같이 구축 할 수 쿼리 그룹을 정의합니다 :

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 블록을 허용하지 않습니다 - 이후 query의 이전을 대체. instance_eval과 같은 것을 사용하여 쿼리 블록의 올바른 컨텍스트에서 여러 블록을 실행할 수 있습니까?

답변

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 

나는이 질문을하기 전에 나는이 시도했던 거의 확신했다,하지만 난 생각 전에 엉망이 됐어.

+0

용어가 다음과 같은 필터와 함께 작동하는지 알고 싶습니다. 나는 그것을 시도했다. 마지막 proc만이 instance_eval이 될 것으로 보인다. ES를 보낸다. 고마워. – brupm

0

나는 타이어에 익숙하지 않지만 elasticsearch에서 경험이있다. DSL 쿼리. 문제는 검색 API가 _search 엔드 포인트로 전송되는 JSON에서 "query": {...} 중 하나만 허용한다는 것입니다.

하나 이상의 검색어가있는 경우이를 어떻게 생각합니까? elasticsearch에서 검색어 조합 방법을 어떻게 알 수 있습니까? 다른 bool 쿼리를 사용해야합니다.

"query"은 (아마도 큰) 쿼리 트리의 루트이며 두 개 이상의 루트를 가질 수 없습니다!

희망 ...

+0

감사합니다. 나는 그 제약에 만족한다고 생각합니다. 어쩌면 그 제목이 오해의 소지가 있었을 지 모르지만 Ruby에서 하나의 쿼리를 구축 할 수 있지만 별도의 Ruby 메소드 호출을 통해 얻을 수있는 방법을 발견하게되어 정말 기쁩니다. – Gareth

+0

나는 루비를 도울 수 없어 두렵다.하지만 나는 elastica (타이어와 동등)와 비슷한 PHP에서 비슷한 일을했다. 나는 배열의 끝에 질의를 추가하여 루트'bool' 쿼리 ('must' 또는'should' 절)에 추가 된 메소드를 가졌습니다. 'function addShould ($ newQuery) {$ this-> should [] = $ newQuery; } ' – ramseykhalaf

0

설명서에 설명되어 있습니다. 여기를 확인 http://karmi.github.io/tire/#section-84.

당신은

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

처럼 전화를 그냥 자신의 람다를 구축 할 수 있습니다.