web-dev-qa-db-fra.com

Problème de tiret de recherche élastique avec filtre de terme

J'ai la requête Elastic Search suivante avec uniquement un filtre de terme. Ma requête est beaucoup plus complexe, mais j'essaie simplement de montrer le problème ici.

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

Lorsque je transmets une valeur coupée au filtre, je n'obtiens aucun résultat. Mais si j'essaie sans valeur sans césure, j'obtiens des résultats. Je ne sais pas si le trait d'union est un problème ici mais mon scénario me le fait croire.

Existe-t-il un moyen d'échapper au trait d'union pour que le filtre renvoie des résultats? J'ai essayé d'échapper au tiret avec une barre oblique inverse que j'ai lue sur les forums Lucene mais cela n'a pas aidé.

De plus, si je passe une valeur GUID dans ce champ qui est coupé et entouré par des accolades, quelque chose comme - {ASD23-34SD-DFE1-42FWW}, aurais-je besoin de minuscule le les caractères de l'alphabet et aurais-je besoin d'échapper aux accolades aussi?

Merci

48
Gabbar

Je suppose que votre champ est analysé, ce qui est le paramètre par défaut pour les champs de chaîne dans elasticsearch. Par conséquent, quand il est indexé, il n'est pas indexé comme un terme "update-time" mais plutôt comme 2 termes: "update" et "time". C'est pourquoi votre recherche de termes ne trouve pas ce terme. Si votre champ contiendra toujours des valeurs qui devront être complètement mises en correspondance telles quelles, il serait préférable de définir ce champ dans le mappage comme non analysé. Vous pouvez le faire en recréant l'index avec un nouveau mappage:

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

Alternativement, si vous souhaitez une certaine flexibilité dans la recherche d'enregistrements basés sur ce champ, vous pouvez conserver ce champ analysé et utiliser des requêtes de texte à la place:

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

S'il vous plaît, gardez à l'esprit que si votre champ est analysé, cet enregistrement sera trouvé en recherchant uniquement Word "update" ou Word "time".

82
imotov

La réponse acceptée n'a pas fonctionné pour moi avec l'élastique 6.1. Je l'ai résolu en utilisant le champ "mot-clé" qu'élastique fournit par défaut sur les champs de chaîne.

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

Basé sur la réponse de @ imotov Si vous utilisez spring-data-elasticsearch alors tout ce que vous devez faire est de marquer votre champ comme:

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

au lieu de

@Field(type = FieldType.String)

Le problème est que vous devez supprimer l'index et le ré-instancier avec de nouveaux mappages.

1
Innokenty