2012-06-08 3 views
4

나는 Elastic Search에서 원하는 방식으로 부스팅 작업을하기 위해 고심하고 있습니다.범위 대 탄성 검색의 용어 부스트

성별, 관심사 및 나이가 포함 된 프로필이 색인 생성되어 있다고 가정 해 봅시다. 성별이 일치하는 것이 가장 적절하다고 판단하면 관심 분야와 가장 중요하지 않은 기준은 사용자의 연령입니다. 나는 위의 쿼리가 방금 언급 한 원칙에 따라 일치하는 프로파일의 순서로 결과를 얻을 것으로 기대했지만, 나는 그것을 실행했을 때 먼저 남성을 몇 명 얻었고 차를 좋아하는 여성 마리아가되기 전에 50 세 여성 암자를 얻는다. ... 왜 마리아가 안나보다 높은 점수를 얻지 못하니 ??

{ 
    "query": { 
     "bool" : { 
      "should" : [ 
       { "term" : { "gender" : { "term": "male", "boost": 10.0 } } }, 
       { "term" : { "likes" : { "term": "cars", "boost" : 5.0 } } }, 
       { "range" : { "age" : { "from" : 50, "boost" : 1.0 } } } 
      ], 
      "minimum_number_should_match" : 1 
     } 
    }  
} 
크게 이해할 것이다

힌트

스타 인


이 실행 컬 명령이다 :

$ curl -XPUT http://localhost:9200/users/profile/1 -d '{ 
    "nickname" : "bob", 
    "gender" : "male", 
    "age" : 48, 
    "likes" : "airplanes" 
}' 

$ curl -XPUT http://localhost:9200/users/profile/2 -d '{ 
    "nickname" : "carlos", 
    "gender" : "male", 
    "age" : 24, 
    "likes" : "food" 
}' 

$ curl -XPUT http://localhost:9200/users/profile/3 -d '{ 
    "nickname" : "julio", 
    "gender" : "male", 
    "age" : 18, 
    "likes" : "ladies" 
}' 

$ curl -XPUT http://localhost:9200/users/profile/4 -d '{ 
    "nickname" : "maria", 
    "gender" : "female", 
    "age" : 25, 
    "likes" : "cars" 
}' 

$ curl -XPUT http://localhost:9200/users/profile/5 -d '{ 
    "nickname" : "anna", 
    "gender" : "female", 
    "age" : 50, 
    "likes" : "clothes" 
}' 

$ curl -XGET http://localhost:9200/users/profile/_search -d '{ 
    "query": { 
     "bool" : { 
      "should" : [ 
       { "term" : { "gender" : { "term": "male", "boost": 10.0 } } }, 
       { "term" : { "likes" : { "term": "cars", "boost" : 5.0 } } }, 
       { "range" : { "age" : { "from" : 50, "boost" : 1.0 } } } 
      ], 
      "minimum_number_should_match" : 1 
     } 
    }  
}' 
+0

부스트 C++ 라이브러리 용 태그입니다. 태그를 편집 할 수 있습니까? – Vikas

+0

부스트 태그가 삭제되었습니다. – DrTech

답변

12

boost 값은 절대적이지 - 그것은에 combined with other factors 인 각 용어의 관련성을 결정하십시오.

당신은 두 개의 "성별"을 가졌지 만 많은 다른 "좋아하는 것"이 ​​있습니다. 따라서 male은 데이터 내에서 자주 발생하기 때문에 거의 무의미한 것으로 간주됩니다. 그러나 cars은 몇 번 발생할 수 있으므로 더 적절하다고 간주됩니다.

이 논리는 전체 텍스트 검색에는 유용하지만 기본적으로 필터로 사용되도록 설정된 enum에는 유용하지 않습니다.

다행히도 omit_term_freq_and_positionsomit_norms을 사용하여 필드 당 기준으로이 기능을 사용 중지 할 수 있습니다.

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "test" : { 
     "properties" : { 
      "likes" : { 
       "index" : "not_analyzed", 
       "omit_term_freq_and_positions" : 1, 
       "omit_norms" : 1, 
       "type" : "string" 
      }, 
      "gender" : { 
       "index" : "not_analyzed", 
       "omit_term_freq_and_positions" : 1, 
       "omit_norms" : 1, 
       "type" : "string" 
      }, 
      "age" : { 
       "type" : "integer" 
      } 
     } 
     } 
    } 
} 
' 

UPDATE :

는 다음과 같이 매핑을 설정하십시오 전체 작업 예 :

기존 인덱스 삭제 :

curl -XDELETE 'http://127.0.0.1:9200/users/?pretty=1' 

새로운 매핑 인덱스 만들기를 :

curl -XPUT 'http://127.0.0.1:9200/users/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "profile" : { 
     "properties" : { 
      "likes" : { 
       "index" : "not_analyzed", 
       "omit_term_freq_and_positions" : 1, 
       "type" : "string", 
       "omit_norms" : 1 
      }, 
      "age" : { 
       "type" : "integer" 
      }, 
      "gender" : { 
       "index" : "not_analyzed", 
       "omit_term_freq_and_positions" : 1, 
       "type" : "string", 
       "omit_norms" : 1 
      } 
     } 
     } 
    } 
} 
' 

지수 테스트 문서 :

curl -XPOST 'http://127.0.0.1:9200/users/_refresh?pretty=1' 

검색 :

curl -XGET 'http://127.0.0.1:9200/users/profile/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "bool" : { 
     "minimum_number_should_match" : 1, 
     "should" : [ 
      { 
       "term" : { 
        "gender" : { 
        "boost" : 10, 
        "term" : "male" 
        } 
       } 
      }, 
      { 
       "term" : { 
        "likes" : { 
        "boost" : 5, 
        "term" : "cars" 
        } 
       } 
      }, 
      { 
       "range" : { 
        "age" : { 
        "boost" : 1, 
        "from" : 50 
        } 
       } 
      } 
     ] 
     } 
    } 
} 
' 

결과

curl -XPOST 'http://127.0.0.1:9200/users/profile/_bulk?pretty=1' -d ' 
{"index" : {"_id" : 1}} 
{"nickname" : "bob", "likes" : "airplanes", "age" : 48, "gender" : "male"} 
{"index" : {"_id" : 2}} 
{"nickname" : "carlos", "likes" : "food", "age" : 24, "gender" : "male"} 
{"index" : {"_id" : 3}} 
{"nickname" : "julio", "likes" : "ladies", "age" : 18, "gender" : "male"} 
{"index" : {"_id" : 4}} 
{"nickname" : "maria", "likes" : "cars", "age" : 25, "gender" : "female"} 
{"index" : {"_id" : 5}} 
{"nickname" : "anna", "likes" : "clothes", "age" : 50, "gender" : "female"} 
' 

은 (최신 문서 검색에 표시되는지 확인하기 위해) 인덱스를 새로 고침 :

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "nickname" : "bob", 
#    "likes" : "airplanes", 
#    "age" : 48, 
#    "gender" : "male" 
#    }, 
#    "_score" : 0.053500723, 
#    "_index" : "users", 
#    "_id" : "1", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "carlos", 
#    "likes" : "food", 
#    "age" : 24, 
#    "gender" : "male" 
#    }, 
#    "_score" : 0.053500723, 
#    "_index" : "users", 
#    "_id" : "2", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "julio", 
#    "likes" : "ladies", 
#    "age" : 18, 
#    "gender" : "male" 
#    }, 
#    "_score" : 0.053500723, 
#    "_index" : "users", 
#    "_id" : "3", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "anna", 
#    "likes" : "clothes", 
#    "age" : 50, 
#    "gender" : "female" 
#    }, 
#    "_score" : 0.029695695, 
#    "_index" : "users", 
#    "_id" : "5", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "maria", 
#    "likes" : "cars", 
#    "age" : 25, 
#    "gender" : "female" 
#    }, 
#    "_score" : 0.015511602, 
#    "_index" : "users", 
#    "_id" : "4", 
#    "_type" : "profile" 
#   } 
#  ], 
#  "max_score" : 0.053500723, 
#  "total" : 5 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "took" : 4 
# } 

UPDATE : 다른 방법 여기

, 나는 더 자세한 동안, 당신에게 훨씬 더 예측 가능한 결과를 제공, 다른 쿼리를 제시한다. 여기에는 custom filters score query을 사용합니다. 먼저, 조건 중 하나 이상과 일치하는 문서로 필터를 필터링합니다.

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "custom_filters_score" : { 
     "query" : { 
      "constant_score" : { 
       "filter" : { 
        "or" : [ 
        { 
         "term" : { 
          "gender" : "male" 
         } 
        }, 
        { 
         "term" : { 
          "likes" : "cars" 
         } 
        }, 
        { 
         "range" : { 
          "age" : { 
           "gte" : 50 
          } 
         } 
        } 
        ] 
       } 
      } 
     }, 
     "score_mode" : "total", 
     "filters" : [ 
      { 
       "boost" : "10", 
       "filter" : { 
        "term" : { 
        "gender" : "male" 
        } 
       } 
      }, 
      { 
       "boost" : "5", 
       "filter" : { 
        "term" : { 
        "likes" : "cars" 
        } 
       } 
      }, 
      { 
       "boost" : "1", 
       "filter" : { 
        "range" : { 
        "age" : { 
         "gte" : 50 
        } 
        } 
       } 
      } 
     ] 
     } 
    } 
} 
' 

당신은 점수 관련된 것을 볼 수 있습니다 : 우리는 constant score 쿼리를 사용하기 때문에이 필터에 일치하는 경우, 모든 문서 필터 점수를 사용자 정의 우리가 각 문서를 높일 수 있습니다 1.

의 초기 점수가 각 문서와 함께 멋진 라운드 번호는 쉽게 일치하는 절로 추적됩니다.

# [Fri Jun 8 21:30:24 2012] Response: 
# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "nickname" : "bob", 
#    "likes" : "airplanes", 
#    "age" : 48, 
#    "gender" : "male" 
#    }, 
#    "_score" : 10, 
#    "_index" : "users", 
#    "_id" : "1", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "carlos", 
#    "likes" : "food", 
#    "age" : 24, 
#    "gender" : "male" 
#    }, 
#    "_score" : 10, 
#    "_index" : "users", 
#    "_id" : "2", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "julio", 
#    "likes" : "ladies", 
#    "age" : 18, 
#    "gender" : "male" 
#    }, 
#    "_score" : 10, 
#    "_index" : "users", 
#    "_id" : "3", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "maria", 
#    "likes" : "cars", 
#    "age" : 25, 
#    "gender" : "female" 
#    }, 
#    "_score" : 5, 
#    "_index" : "users", 
#    "_id" : "4", 
#    "_type" : "profile" 
#   }, 
#   { 
#    "_source" : { 
#    "nickname" : "anna", 
#    "likes" : "clothes", 
#    "age" : 50, 
#    "gender" : "female" 
#    }, 
#    "_score" : 1, 
#    "_index" : "users", 
#    "_id" : "5", 
#    "_type" : "profile" 
#   } 
#  ], 
#  "max_score" : 10, 
#  "total" : 5 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 20, 
#  "total" : 20 
# }, 
# "took" : 6 
# } 
+0

정말 감사합니다. 답변 : 감사합니다. 분명히 이해할 수있는 부분이 많습니다. 매핑! 나는 결과에서 안나를 전혀 포함하지 않는 내 쿼리 결과로 당신이 제안한 매핑을 설정하려 했습니까? – Stine

+0

내가이 매핑에 대해 배울 수있는 곳을 알고 있습니까? – Stine

+0

뭔가 잘못 했어야합니다. 위에 작동하는 예제를 추가했습니다. 맵핑에 대해 배울 때, http://www.elasticsearch.org/guide/reference/mapping/ – DrTech

관련 문제