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?
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."
utiliser une requête générique:
'{"query":{ "wildcard": { "text.keyword" : "*google*" }}}'
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.*"}
}
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.
Pour la correspondance de texte partielle et complète, les éléments suivants ont fonctionné
"query" : {
"query_string" : {
"query" : "*searchText*",
"fields" : [
"fieldName"
]
}
Pour une correspondance partielle, vous pouvez utiliser prefix ou match_phrase_prefix .