2015-02-21 16 views
5

Ho una query multi_match di tipo cross_fields, che voglio migliorare con la corrispondenza del prefisso.Ricerca elastica multi_match prefisso cross_fields

{ 
    "index": "companies", 
    "size": 25, 
    "from": 0, 
    "body": { 
    "_source": { 
     "include": [ 
     "name", 
     "address" 
     ] 
    }, 
    "query": { 
     "filtered": { 
     "query": { 
      "multi_match": { 
      "type": "cross_fields", 
      "query": "Google", 
      "operator": "and", 
      "fields": [ 
       "name", 
       "address" 
      ] 
      } 
     } 
     } 
    } 
    } 
} 

Si sta abbinando perfettamente su query come il google mountain view. L'array filtered è lì perché ho bisogno di aggiungere dinamicamente i filtri geografici.

{ 
    "id": 1, 
    "name": "Google", 
    "address": "Mountain View" 
} 

Ora voglio permettere corrispondenza prefisso, senza rompere cross_fields.

query come questi devono corrispondere:

  • goog
  • google mount
  • google mountain vi
  • mountain view goo

Se cambio la multi_match.type-phrase_prefix, corrisponde l'intera query un singolo campo, quindi corrisponde solo a mountain vi ma non a google mountain vi

Come posso risolvere questo?

risposta

2

Poiché non vi sono risposte e qualcuno potrebbe vedere questo, ho avuto lo stesso problema e qui è una soluzione:

Utilizzando the edgeNGrams tokenizer.

È necessario modificare le impostazioni dell'indice e i mapping.

Ecco un esempio per le impostazioni:

"settings" : { 
    "index" : { 
    "analysis" : { 
     "analyzer" : { 
     "ngram_analyzer" : { 
      "type" : "custom", 
      "stopwords" : "_none_", 
      "filter" : [ "standard", "lowercase", "asciifolding", "word_delimiter", "no_stop", "ngram_filter" ], 
      "tokenizer" : "standard" 
     }, 
     "default" : { 
      "type" : "custom", 
      "stopwords" : "_none_", 
      "filter" : [ "standard", "lowercase", "asciifolding", "word_delimiter", "no_stop" ], 
      "tokenizer" : "standard" 
     } 
     }, 
     "filter" : { 
     "no_stop" : { 
      "type" : "stop", 
      "stopwords" : "_none_" 
     }, 
     "ngram_filter" : { 
      "type" : "edgeNGram", 
      "min_gram" : "2", 
      "max_gram" : "20" 
     } 
     } 
    } 
    } 
} 

Naturalmente, si dovrebbe adeguare gli analizzatori per il proprio caso d'uso. Potresti voler lasciare intatto l'analizzatore predefinito o aggiungere il filtro ngram su di esso in modo da non dover modificare i mapping. L'ultima soluzione significherebbe che tutti i campi del tuo indice otterranno il filtro ngram.

E per la mappatura:

"mappings" : { 
    "patient" : { 
    "properties" : { 
     "name" : { 
     "type" : "string", 
     "analyzer" : "ngram_analyzer" 
     }, 
     "address" : { 
     "type" : "string", 
     "analyzer" : "ngram_analyzer" 
     } 
    } 
    } 
} 

Declare ogni campo che si desidera completare automaticamente con il ngram_analyzer. Quindi le domande nella tua domanda dovrebbero funzionare. Se tu usassi qualcos'altro, sarei felice di sentirne parlare.

+0

Molto utile per quello che volevo, grazie. – Abubakkar