2014-08-31 4 views
2

elasticsearch (searchkick 포함)를 사용하는 Rails 앱은 _geo_distance 주문 기능을 사용하여 잘 작동하지만 위치를 포함하는보다 복잡한 주문을 수행해야하고 비즈니스 이름 정확한 문자열 일치.레일 elasticsearch _geo_distance 및 사용자 정의 스코어링/정렬

예를 들어, 쿼리를 작성하고 10 개의 오름차순 거리가 반환 된 결과가 있지만 레코드의 비즈니스 이름에 # 5 결과도 정확히 일치하는 문자열 인 경우이를 홍보/승격하고 싶습니다. # 1 위치 (기본적으로 해당 레코드의 거리 정렬 우선 함).

이 문제를 해결하기 위해 볼 수있는 두 가지 방법이 있지만 두 가지 문제가 있습니다.

먼저, 초기 쿼리에서이를 수행하여 elasticsearch에서 작업을 처리하도록합니다.

둘째, elasticsearch에서 반환 한 결과에 대해 특정 유형의 사후 프로세스 재 정렬을 수행하여 정확한 일치를 찾고 필요한 경우 다시 정렬하는 것입니다.

첫 번째 방법의 문제점은 _geo_distance를 호출 할 때 내장 된 채점 메커니즘이 완전히 거리로 이동하여 사용자 정의 채점 기능을 위치와 혼합하는 방법을 궁금하게 만드는 것입니다.

두 번째 방법의 문제는 반환 된 검색 결과가 후 프로세스의 정상적인 배열 또는 해시 정렬 메커니즘을 좋아하지 않는 사용자 지정 유형의 SearchKick 개체라는 점입니다.

이런 방식으로 결과의 문서를 승격시키기 위해 사전 또는 사후 쿼리를 수행하는 방법이 있습니까?

감사합니다.

답변

1

실제로 점수를 "제어"하는 여러 가지 방법이 있습니다. 색인을 생성하기 전에 이미 문서가 높은 점수/부스트를 얻으려는 경우 색인을 생성하기 전에 특수 문서의 점수를 높일 수 있습니다 (here 참조).

색인 생성 전에 부스트를 결정할 수없는 경우 쿼리 명령에서 강조 표시를 높일 수 있습니다. boosting query에 관해서도 많은 옵션이 있으며 사용 된 kind 쿼리에 의존합니다. 쿼리 문자열 쿼리

:

당신은 fields" : ["content", "name.*^5"] 같은 일부 필드를 강화하거나 (이것은 단지 추가 부스트에게, 당신의 이름을 작동 할 수 있습니다) 등 quick^2 fox, 일부 쿼리 명령을 높일 수 있습니다. 다른 사람을 위해

:

당신은 같은 "이반"의 경우 강화로, 용어 쿼리에 대한 활력을 불어 넣을 수 있습니다

"term" : {"name" : {"value" : "ivan","boost" : 10.0}}

당신이 부울 쿼리로 포장하고 원하는을 높일 수 있습니다 케이스. 전의. 'ivan'을 모두 찾아 이름 필드에 'ji'를 올리십시오.

{ "쿼리": { "부울": { "해야": [{ "일치": { "이름": "이반"}}],
"해야": [{ "용어" : { "name": { "value": "ji", "boost": 10}}}}}}

검색어를 제외하면 부스트를 지원하는 쿼리가 많이 있습니다. prefix 쿼리, match 쿼리 상황에 따라 사용할 수 있습니다. 다음은 공식적인 예입니다. http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_boosting_query_clauses.html

정규화가 필요하기 때문에 부스터 링을 제어하기가 쉽지 않을 수 있습니다. function_score 쿼리를 사용하여 점수를 지정하여 직접 점수를 지정할 수 있습니다. 직접 제어해야하는 경우 정말 유용한 쿼리입니다.


즉, 당신은 부울에서 쿼리를 포장 할 수 있으며 다음과 같이 이름 일치에 대한 몇 가지 부스트를 추가 : 자세한 내용은

{ "query" : { 
    "bool" : { 
    "must": [ 
      {"filtered" : { 
      "filter" : { 
       "geo_distance" : { 
        "distance" : "2000km", 
        "loc" : { 
         "lat" : 10, 
         "lon" : 10 
        } 
       } 
      } 
     }}], 
    "should" : [ { "term" : { "name": { "value" : "ivan", "boost" : 10 }}}]}}, 
"sort" : [ 
      "_score", 
    { 
     "_geo_distance" : { 
      "loc" : [10, 10], 
      "order" : "asc", 
      "unit" : "km", 
      "mode" : "min", 
      "distance_type" : "sloppy_arc" 
     } 
    } 
] 
} 

을, 당신은 내 요점 https://gist.github.com/hxuanji/e5acd9a5174ea10c08b8를 확인할 수 있습니다. 나는 "ivan"이름을 부스트한다. 결과적으로 "ivan"문서가 (10,10) 문서보다는 첫 번째 문서가됩니다.

+1

답장을 보내 주셔서 감사합니다. 그러나이 점수가 지리 거리 스코어링/결과와 함께 작동하는 방법에 대해 아직 명확하지 않습니다. 지리 결과는 거리별로 정렬되며, 이는 정상적인 채점 기능을 변경하는 것으로 보입니다. 이 경우 "점수"를 올리면 거리 측정이 잘못 될 수 있습니다. 그렇다면 어떻게하면 Geo 측정 값을 보존하고 문서를 홍보 할 수 있습니까? – kayatela

+0

나는이 방법에 접근하는 또 다른 방법은 _score (geo가 아닌)에 의해 정렬 된 결과를 얻는 것뿐만 아니라 반환 된 결과에 _geo_distance 데이터를 포함시키는 것입니다. 그러나 나는 이것을하는 방법을 알아 내지 못했다. – kayatela

+0

위의 편집을 확인해 보았습니다. – hxuanji