Ecco la soluzione che ho finito con, in base alla risposta di Andrei e ampliato per supportare più termini di ricerca e di punteggio aggiuntivo in base alla durata della prima parola nel risultato:
In primo luogo, definire la seguente analizzatore personalizzato (si mantiene l'intera stringa come un unico token e in minuscolo esso):
"raw_analyzer": {
"type": "custom",
"filter": [
"lowercase"
],
"tokenizer": "keyword"
}
in secondo luogo, definire la mappatura campo di ricerca in questo modo ("nome" della miniera di nome):
"name": {
"type": "string",
"analyzer": "english",
"fields": {
"raw": {
"type": "string",
"index_analyzer": "raw_analyzer",
"search_analyzer": "standard"
}
}
},
"_nameFirstWordLength": {
"type": "long"
}
In terzo luogo, durante il popolamento dell'indice utilizzare la seguente logica (la mia è in C#) per popolare:
_nameFirstWordLength = fi.Name.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)[0].Length
Infine, fare la tua ricerca come segue:
{
"query":{
"bool":{
"must":{
"match_phrase_prefix":{
"name":{
"query":"apple"
}
}
},
"should":{
"function_score":{
"query":{
"query_string":{
"fields":[
"name.raw"
],
"query":"apple*"
}
},
"script_score":{
"script":"100/doc['_nameFirstWordLength'].value"
},
"boost_mode":"replace"
}
}
}
}
}
sto usando match_phrase_prefix in modo che parziale le corrispondenze sono supportate, come "ap" corrispondente a "apple". Il bool deve/dovrebbe con quella seconda query query_string su name.raw dare un punteggio più alto ai risultati il cui nome inizia con uno dei termini di ricerca (nel mio codice sto pre-processando la stringa di ricerca, solo per quella seconda query, a aggiungi un "*" dopo ogni parola). Infine, il wrapping di questa seconda query in uno script function_score che utilizza il valore di _nameFirstWordLength fa sì che i risultati aggiornati dalla seconda query vengano ulteriormente ordinati in base alla lunghezza della prima parola (ad esempio che Apple mostra prima di Applebee, ad esempio).
Forse questo aiuterà http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-advanced-scripting.html –
Avrei iniziato a seguire questa strada fino a quando ho scoperto che lo script non ha accesso alla stringa di ricerca con token :( – IGx89