2015-12-07 10 views
7

muszę uzyskać losową próbkę z indeksem ElasticSearch, czyli wydać kwerendy, która pobiera jakieś dokumenty z danego indeksu z prawdopodobieństwem ważonej Wj/ΣWi (gdzie Wj jest masa rzędu j i Wj/ΣWi jest suma wag wszystkich dokumentów w tym zapytaniu).ważona losowe próbkowanie w Elasticsearch

Obecnie mam następujące zapytanie:

GET products/_search?pretty=true 

{"size":5, 
    "query": { 
    "function_score": { 
     "query": { 
     "bool":{ 
      "must": { 
      "term": 
       {"category_id": "5df3ab90-6e93-0133-7197-04383561729e"} 
      } 
     } 
     }, 
     "functions": 
     [{"random_score":{}}] 
    } 
    }, 
    "sort": [{"_score":{"order":"desc"}}] 
} 

Zwraca 5 produktów z wybranej kategorii, losowo. Każda pozycja ma pole weight. Więc prawdopodobnie muszę użyć

zgodnie z opisem here.

Mam następujące zagadnienia:

  • Co to jest poprawny sposób to zrobić?
  • Czy muszę włączyć Dynamic Scripting?
  • Jak obliczyć całkowitą sumę zapytania?

Bardzo dziękuję za pomoc!

Odpowiedz

0

Wiem, że to pytanie jest stare, ale odpowiada na pytania przyszłych użytkowników.

Wydaje się, że odpowiedź brzmi: comment before yours in the GitHub thread. Jeśli każdy z twoich dokumentów ma względną wagę, możesz wybrać wynik losowy dla każdego dokumentu i pomnożyć go przez wagę, aby utworzyć nowy losowy wynik losowy. Ma to dodatkową zaletę, ponieważ nie wymaga sumy wag.

np. jeśli dwa dokumenty mają wagę 1 i 2, to można oczekiwać, że drugi będzie miał dwukrotnie większe prawdopodobieństwo wyboru jako pierwszy. Daj każdemu dokumentowi losowy wynik między 0 i 1 (który już robisz z "random_score"). Pomnóż losową liczbę punktów według wagi, a otrzymasz pierwszy dokument z wynikiem między 0 i 1, a drugi z wynikiem między 0 i 2, więc dwa razy częściej będzie można wybrać!

1

Jeśli ktoś Ci pomoże, oto jak ostatnio zaimplementowałem ważone tasowanie.

W tym przykładzie przetasujemy firmy. Każda firma ma "company_score" z zakresu od 0 do 100. Dzięki temu prostemu tasowaniu ważonemu firma z wynikiem 100 jest 5 razy bardziej prawdopodobna na pierwszej stronie niż firma z wynikiem 20.

json_body = { 
    "sort": ["_score"], 
    "query": { 
     "function_score": { 
      "query": main_query, # put your main query here 
      "functions": [ 
       { 
        "random_score": {}, 
       }, 
       { 
        "field_value_factor": { 
         "field": "company_score", 
         "modifier": "none", 
         "missing": 0, 
        } 
       } 
      ], 
      # How to combine the result of the two functions 'random_score' and 'field_value_factor'. 
      # This way, on average the combined _score of a company having score 100 will be 5 times as much 
      # as the combined _score of a company having score 20, and thus will be 5 times more likely 
      # to appear on first page. 
      "score_mode": "multiply", 
      # How to combine the result of function_score with the original _score from the query. 
      # We overwrite it as our combined _score (random x company_score) is all we need. 
      "boost_mode": "replace", 
     } 
    } 
}