2014-04-23 17 views
5

Sto costruendo una funzione di completamento automatico utilizzando ElasticSearch. Mentre l'utente digita, voglio mostrare un elenco di completamenti dai dati, in modo che l'utente possa selezionarne uno. Ad esempio, se i dati contiene le seguenti frasi:Ricerca prefisso frase ElasticSearch - Come ottengo la frase abbinata?

very unusual 
very unlikely 
very useful 

ed i tipi di utente:

very u 

Voglio visualizzare le frasi di cui sopra.

sto usando questa query:

"query": { 
    "multi_match": { 
     "query": "very u", 
     "fields": [ 
     "name", 
     "description", 
     "contentBlocks.caption", 
     "contentBlocks.text" 
     ], 
     "type": "phrase_prefix", 
     "max_expansions": 10, 
     "cutoff_frequency": 0.001 
    } 

Questo corrisponde al contenuto che sto cercando, ma l'estrazione le frasi corrispondenti dai risultati della ricerca è abbastanza imbarazzante. Utilizzo l'evidenziazione e raccolgo le frasi corrispondenti analizzando i momenti salienti. Ad esempio:

"highlight": { 
     "contentBlocks.text": [ 
     "turned the <em>very</em> <em>unusual</em> doorknob" 
     ] 
    } 

    "highlight": { 
     "contentBlocks.text": [ 
     "invented a <em>very</em> <em>useful</em> mechanism" 
     ] 
    } 

Qual è il modo giusto per farlo?


"Frase Suggester" potrebbe essere in grado di fare ciò che ho descritto, ma non è affatto ovvio come si potrebbe arrivare a fare questo.

ho indicizzati i campi di interesse (ad esempio, "descrizione") come segue:

"description" : { 
    "index_analyzer" : "snowball_stem", 
    "search_analyzer" : "snowball_stem", 
    "type" : "string", 
    "fields" : { 
     "autocomplete" : { 
     "index_analyzer" : "shingle_analyzer", 
     "search_analyzer" : "shingle_analyzer", 
     "type" : "string" 
     } 
    } 
    }, 

Sto usando l'analizzatore snowball_stem per la ricerca, e la shingle_analyzer per la funzione di completamento automatico. shingle_analyzer assomiglia a questo:

"settings" : { 
    "analysis" : { 
     "analyzer" : { 
      "shingle_analyzer" : { 
       "type" : "custom", 
       "tokenizer" : "standard", 
       "filter" : [ 
        "standard", 
        "lowercase", 
        "shingle_filter" 
       ], 
       "char_filter" : [ 
        "html_strip" 
       ] 
      } 
     }, 
     "filter" : { 
      "shingle_filter" : { 
       "type" : "shingle", 
       "min_shingle_size" : 2, 
       "max_shingle_size" : 2 
      } 
     } 
    } 
}, 

La documentazione per la frase suggester sembra essere totalmente orientata verso "correzione ortografica", piuttosto che il completamento. Dal momento che quello che sto cercando è il completamento, ho impostato min_word_length del generatore diretto e prefix_length alla lunghezza del testo di input, in questo caso, 2.

ho artigianale una query suggerimento sulla base della documentazione:

{ 
    "text" : "sa", 
    "autocomplete_description" : { 
     "phrase" : { 
      "analyzer" : "standard", 
      "field" : "description.autocomplete", 
      "size" : 10, 
      "max_errors" : 2, 
      "confidence" : 0.0, 
      "gram_size" : 2, 
      "direct_generator" : [ 
       { 
        "field" : "description.autocomplete", 
        "suggest_mode" : "always", 
        "size" : 10, 
        "min_word_length" : 2, 
        "prefix_length" : 2 
       } 
      ] 
     } 
    } 
} 

Questa ricerca di suggerimenti per "sa" si presenta con i seguenti risultati:

{ 
    "_shards" : { 
    "total" : 1, 
    "successful" : 1, 
    "failed" : 0 
    }, 
    "autocomplete_description" : [ { 
    "text" : "sa", 
    "offset" : 0, 
    "length" : 2, 
    "options" : [ { 
     "text" : "say", 
     "score" : 0.012580795 
    }, { 
     "text" : "sa", 
     "score" : 0.01127677 
    }, { 
     "text" : "san", 
     "score" : 0.0106529845 
    }, { 
     "text" : "sad", 
     "score" : 0.008533429 
    }, { 
     "text" : "saw", 
     "score" : 0.008107899 
    }, { 
     "text" : "sam", 
     "score" : 0.007155634 
    } ] 
    } ] 
} 

quello che mi aspettavo di trovare per l'ingresso "sa" è parole che iniziano con "sa" di qualsiasi lunghezza. Perché restituisce solo parole di due o tre caratteri? Perché restituisce solo sei opzioni? La query phrase_prefix multi_match che ho utilizzato trova molte parole più lunghe che iniziano con "sa", come "saving", "sassy", "safari" e "salad".

Quando cerco suggerimenti per testi di più parole, come "uno o" (che si verificano molte volte nei dati), non trova nulla. La query phrase_prefix multi_match trova "uno o più", "uno o il", "uno o tu" e "uno o entrambi".

Come posso convincere questo suggester a fare ciò che voglio?

+0

Fatemi sapere se avete domande, o posso aggiungere qualsiasi cosa alla mia risposta. –

+0

darò un'occhiata. –

+0

Ho provato a usare la frase suggester per fare questo, ma non ho avuto molto successo. Ho aggiunto informazioni sui miei esperimenti e domande più dettagliate sulla descrizione del problema di cui sopra. –

risposta

1

È possibile ottenere più o meno ciò che si desidera con il completion suggester. Il problema principale con questo è che non è più alla ricerca di informazioni.È possibile risolvere questo problema aggiungendo in un suggester context ma funziona solo per i filtri e non tiene conto del testo di ricerca.

L'unico modo che conosco per ottenere i "migliori" di comportamento (Context Aware completamenti di ricerca) è quello di effettuare le seguenti operazioni:

  • creare un campo suggestions in cui il testo è in formato token come si vorrebbe che per essere visto dall'utente (probabilmente un analizzatore standard o magari aggiungere un filtro token 2-shingle).
  • Supponiamo che l'utente emetta la query incompleta very un. Il problema dietro le quinte ricerca very e quindi utilizza term aggregations per ottenere termini di elenco corrispondenti al contesto di ricerca, ma limitare i termini restituiti con "include": "un.*".
  • L'elenco risultante avrà l'aspetto [insolito, improbabile, non freddo].

L'unico problema con questo metodo, soprattutto in un ambiente sharded è che si tratta di un sacco di domande e si sta tirando un campo cardinalità molto alto (suggestions) in memoria. Quindi ... non so se questo è praticamente fattibile. Quindi forse è meglio tornare con il suggester di completamento. Se provi uno di questi, sono interessato a sentire la tua esperienza con esso.

+1

Grazie per l'esame, @JnBrymn. Ho finito per utilizzare il codice che ho descritto in origine, utilizzando la query phrase_prefix e post-elaborazione dei momenti salienti. Sembra un trucco, ma funziona in modo affidabile e le prestazioni sono sorprendentemente buone. –

Problemi correlati