web-dev-qa-db-fra.com

Comment faire une correspondance partielle dans Elasticsearch?

J'ai un lien tel que http://drive.google.com et je souhaite faire correspondre le lien "google" au lien. 

J'ai:

query: {
    bool : {
        must: {
            match: { text: 'google'} 
        }
    }
}

Mais cela ne correspond que si tout le texte est "google" (insensible à la casse, donc cela correspond également à Google ou à GooLe, etc.). Comment faire correspondre le "google" à l'intérieur d'une autre chaîne?

12
PraneethVT

Le fait est que l'expression rationnelle ElasticSearch que vous utilisez nécessite une correspondance de chaîne complète :

_ {Les motifs de Lucene sont toujours ancrés}. Le modèle fourni doit correspondre à la chaîne entière.

Ainsi, pour faire correspondre n'importe quel caractère (sauf une nouvelle ligne), vous pouvez utiliser le modèle .*:

match: { text: '.*google.*'}
                ^^      ^^

Une autre variante concerne les cas où votre chaîne peut avoir des nouvelles lignes: match: { text: '(.|\n)*google(.|\n)*'}. Ce (.|\n)* épouvantable est un must dans ElasticSearch car cette variante de regex ne permet aucune solution de contournement [\s\S] ni aucun indicateur DOTALL/Singleline. "Le moteur des expressions régulières Lucene n'est pas compatible avec Perl, mais prend en charge un plus petit nombre d'opérateurs."

7

utiliser une requête générique:

'{"query":{ "wildcard": { "text.keyword" : "*google*" }}}'
5
weijh

Je n'arrive pas à trouver un break change désactivant les expressions régulières dans match, mais match: { text: '.*google.*'} ne fonctionne sur aucun de mes clusters Elasticsearch 6.2. Peut-être est-ce configurable?

Regexp fonctionne:

"query": {
   "regexp": { "text": ".*google.*"} 
}
2
Steven Ensslen

Pour une solution plus générique, vous pouvez utiliser un autre analyseur ou définir le vôtre. Je suppose que vous utilisez l’analyseur standard qui séparerait http://drive.google.com en jetons "http" et "drive.google.com". C'est pourquoi la recherche de Google uniquement ne fonctionne pas car elle tente de la comparer à l'intégralité de "drive.google.com". 

Si, au lieu de cela, vous indexiez vos documents à l'aide d'un simple analyseur, il serait divisé en "http", "lecteur", "google" et "com". Cela vous permettra de faire correspondre n'importe qui de ces termes. 

1

Pour la correspondance de texte partielle et complète, les éléments suivants ont fonctionné

"query" : {
    "query_string" : {
      "query" : "*searchText*",
      "fields" : [
        "fieldName"
      ]
    }
1
Priya darshini M

Pour une correspondance partielle, vous pouvez utiliser prefix ou match_phrase_prefix .