2015-12-07 12 views
7

devo ottenere un campione casuale da un indice elasticsearch, cioè di rilasciare una query che recupera alcuni documenti da un determinato indice con probabilità pesata Wj/ΣWi (dove Wj è un peso di fila j e Wj/ΣWi è un somma di pesi di tutti i documenti in questa query).ponderato campionamento casuale in elasticsearch

Attualmente, ho la seguente query:

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"}}] 
} 

Esso restituisce 5 articoli della categoria selezionata, in modo casuale. Ogni articolo ha un campo weight. Quindi, probabilmente dovrò usare

"script_score": { 
    "script": "weight = data['weight'].value/SUM; if (_score.doubleValue() > weight) {return 1;} else {return 0;}" 
} 

come descritto here.

ho i seguenti problemi:

  • Qual è il modo corretto di fare questo?
  • Devo abilitare Dynamic Scripting?
  • Come calcolare la somma totale della query?

Grazie mille per il vostro aiuto!

risposta

0

So che questa domanda è vecchia, ma risponde a eventuali futuri utenti.

Il comment before yours in the GitHub thread sembra avere la risposta. Se ognuno dei tuoi documenti ha un peso relativo, puoi scegliere un punteggio casuale per ciascun documento e moltiplicarlo per il peso per creare il tuo nuovo punteggio casuale ponderato. Questo ha il vantaggio di non aver bisogno della somma dei pesi.

ad es. se due documenti hanno pesi 1 e 2, allora ci si aspetterebbe che il secondo abbia il doppio della probabilità di selezione del primo. Assegna a ogni documento un punteggio casuale compreso tra 0 e 1 (che stai già facendo con "random_score"). Moltiplicare il punteggio casuale per il peso e avrai il primo documento con un punteggio compreso tra 0 e 1 e il secondo con un punteggio compreso tra 0 e 2, quindi il doppio delle probabilità di essere selezionato!

1

Nel caso in cui aiuti qualcuno, ecco come ho implementato di recente un shuffling ponderato.

In questo esempio, mescoliamo le società. Ogni azienda ha un "company_score" tra 0 e 100. Con questo semplice rimescolamento ponderata, una società con punteggio di 100 è 5 volte più probabilità di apparire in prima pagina di una società con punteggio 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", 
     } 
    } 
}