2012-07-19 29 views
46

Ho la seguente query di ricerca elastica con solo un filtro di termini. La mia richiesta è molto più complessa, ma sto solo cercando di mostrare il problema qui.Problema di ricerca elastico Problema con filtro a termine

{ 
    "filter": { 
      "term": { 
        "field": "update-time" 
       } 
     } 
} 

Quando si passa in un valore sillabato al filtro, ottengo zero risultati indietro. Ma se provo senza un valore senza sintesi ottengo risultati indietro. Non sono sicuro che il trattino sia un problema qui, ma il mio scenario mi fa credere così.

C'è un modo per uscire dal trattino in modo che il filtro restituisca risultati? Ho provato a sfuggire al trattino con una barra rovesciata che ho letto dai forum di Lucene ma che non mi ha aiutato.

Inoltre, se si passa un valore GUID in questo campo che è sillabato e circondato da parentesi graffe, qualcosa come - {ASD23-34SD-DFE1-42FWW}, avrei bisogno di minuscole maiuscole e caratteri alfabetici bisogno di sfuggire anche alle parentesi graffe?

Grazie

+0

ho sprecato un solo giorno per capire che il problema di non ottenere alcun documento schiena non è stato a causa di un cattivo query, ma a causa di un trattino nel mio esempio di prova ... –

risposta

79

Direi che il vostro campo viene analizzato, che è l'impostazione predefinita per i campi stringa in elasticsearch. Di conseguenza, quando viene indicizzato non è indicizzato come un termine "aggiornamento-tempo" ma come 2 termini: "aggiornamento" e "tempo". Ecco perché la tua ricerca per termini non può trovare questo termine. Se il tuo campo conterrà sempre valori che dovranno essere abbinati completamente così com'è, sarebbe meglio definire tale campo nella mappatura come non analizzato. Si può fare ricreando l'indice con la nuova mappatura:

curl -XPUT http://localhost:9200/your-index -d '{ 
    "mappings" : { 
     "your-type" : { 
      "properties" : { 
       "field" : { "type": "string", "index" : "not_analyzed" } 
      } 
     } 
    } 
}' 

curl -XPUT http://localhost:9200/your-index/your-type/1 -d '{ 
    "field" : "update-time" 
}' 

curl -XPOST http://localhost:9200/your-index/your-type/_search -d'{ 
    "filter": { 
     "term": { 
       "field": "update-time" 
     } 
    } 
}' 

In alternativa, se si vuole una certa flessibilità nella ricerca di record in base a questo campo, è possibile mantenere questo campo ha analizzato e utilizzare le query di testo invece:

curl -XPOST http://localhost:9200/your-index/your-type/_search -d'{ 
    "query": { 
     "text": { 
       "field": "update-time" 
     } 
    } 
}' 

Per favore, tieni presente che se il tuo campo viene analizzato, questo record verrà trovato cercando solo la parola "aggiornamento" o la parola "ora".

+0

Stavo per aggiungere questo come risposta Grazie per la spiegazione dettagliata. – Gabbar

+2

Ottima risposta. Potresti voler cambiare il "testo" in "corrispondenza". Sembrava elasticsearch testo deprecato e sostituito con corrispondenza. – khuderm

0

Sulla base della risposta da @imotov Se stai usando spring-data-elasticsearch allora tutto quello che dovete fare è contrassegnare il campo come:

@Field(type = FieldType.String, index = FieldIndex.not_analyzed) 

invece di

@Field(type = FieldType.String) 

Il problema è che devi rilasciare l'indice e riattivarlo con nuove mappature.

1

La risposta accettata non ha funzionato per me con l'elastico 6.1. L'ho risolto utilizzando il campo "parola chiave" che elastico fornisce di default sui campi stringa.

{ 
    "filter": { 
      "term": { 
        "field.keyword": "update-time" 
       } 
     } 
}