2017-06-08 11 views
0

Je ne suis actuellement pas en ligne avec Elasticsearch. J'ai indexé quelques messages EDIFACT (un format de données pré-historique ;-) Le contenu ressemble à ceci:Rechercher une expression exacte avec Elasticsearch

UNB+UNOA:2+SENDER+RECEIVER+170509:0050+152538' 
UNH+66304+CODECO:D:95B:UN:ITG12' 
BGM+34+INGATE OF UCN ABCD+9' 

Quand je fais une recherche de la phrase UNH + 66304 + CODECO: D: 95B il ne devrait retourner qu'un seul hit mais il semble qu'il retourne tous les fichiers qui contiennent un de ces mots (et UNH est dans chacun des documents). Ma Recherche est la suivante:

curl -XGET --netrc-file ~/curl_user 'localhost:9200/edi/message/_search?pretty' -H 'Content-Type: application/json' -d' 
{ 
    "query":{ 
     "match":{"MESSAGE":"UNH+66304+CODECO:D:95B"} 
    } 
}' 

J'ai essayé d'ajouter le « et » opérateur comme ceci:

"match":{ 
       "MESSAGE":{ 
       "query":"UNH+66304+CODECO", 
       "operator": "and" 

       } 
      } 

Mais aucun résultat sont renvoyés. J'ai lu la suggestion ici: Searching for exact phrase que j'ai besoin d'utiliser des guillemets doubles. J'ai essayé à la fois "requête": "'UNH + 66304 + CODECO'" et "requête": "\" UNH + 66304 + CODECO \ "" mais cela ne fait pas de différence.

J'ai aussi essayé match_phrase

"match_phrase":{ 
       "MESSAGE":{ 
       "query":"UNH+66304+CODECO" 

       } 
      } 

ne retourne pas un résultat en

"match_phrase":{ 
       "MESSAGE":{ 
       "query":"UNH+66304" 

       } 
      } 

fait. Avec le texte normal, cela semble fonctionner mais Elasticsearch ne l'aime pas avec le +: etc dans la chaîne de recherche (qui fait malheureusement partie d'EDIFACT).

How to make query_string search exact phrase in ElasticSearch parle d'utiliser un analyseur différent si vous voulez des correspondances exactes?

Mise à jour: abhishek mishra a confirmé que l'analyseur est probablement le chemin à parcourir. J'utilise Elasticsearch 5.4 et il y a beaucoup d'analyseurs parmi lesquels choisir: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-analyzers.html

L'analyseur de mots-clés correspondrait probablement à ce qu'abhishek a suggéré comme «non analysé» car il s'agit d'un analyseur noop. Cependant, je suis un peu inquiet de l'utiliser car les messages peuvent être assez longs. Quels sont les impacts sur les performances de la recherche? Si j'utilise l'analyseur de mot-clé, serai-je toujours en mesure de rechercher des parties du message entier?

Je me demande si le Pattern Analyzer serait un bon choix? messages EDIFACT sont constitués de segments commençant par 3 caractères Majuscules et sont terminés par « (mais vous pouvez échapper » en préfixant avec?)

FTX+AAA++It?'s a strange data format' 
FTX+AAA++Yes it is' 

Ainsi, l'exemple ci-dessus deux segments. Si j'utilisais un modèle qui sépare ces segments, serait-ce un bon match?

Seul problème est que actuellement le champ MESSAGE peut contenir des messages EDIFACT et des messages XML. Utiliser le même Pattern Analyzer ne fonctionnerait pas je suppose que je devrais créer deux types différents en fonction du contenu du champ MESSAGE (tout le reste est le même).

2ème mise à jour: J'ai suivi le conseil de se pencher sur les analyseurs. Je pensais que l'analyseur de mots clés n'est probablement pas une bonne idée car le texte peut être assez long. J'ai trouvé que l'analyseur de modèle (sans n'importe quel modèle fait sur commande) fonctionne assez bien.Il divise tout sur: et +. Recherches comme

{ 
    "query":{ 
     "match_phrase":{"MESSAGE":"RFF+ABT:ATB150538080520172452"} 
    } 
} 

ou

{ 
     "query":{ 
      "match_phrase":{"MESSAGE":"RFF+ABT:ATB150538080520172452"} 
     } 
    } 

travaille maintenant. Le problème auparavant était que, par exemple, a été divisé en [rff, abt: atb150538080520172452].

Répondre

1

La solution était de utiliser l'analyseur de modèle. Sans avoir à le configurer (pas de motif personnalisé spécifié), il casse le message EDIFACT le long des caractères non-mots/chiffres.

Le problème avec l'analyseur standard était qu'il se comportait bizarrement avec ':'. Donc, si vous, par ex. avait RFF + ATB: AB12345; il l'a décomposé en [rff, atb: ab12345] donc une recherche de ab12345 n'a rien retourné.

Vous pouvez tester comment un analyseur ou tokenizer fonctionne en utilisant

curl -XPOST --netrc-file ~/curl_user 'localhost:9200/_analyze?pretty' -H 'Content-Type: application/json' -d' 
{ 
    "analyzer": "standard", 
    "text":  "UNB+UNOA:2+SENDER+RECEIVER+170513:0452+129910165" 
}' 

Vous pouvez remplacer « analyseur » avec tokenizer si vous voulez juste tester le tokenizer utilisé.

0

Je pense que vous avez « requête » et « match_phrase » inversé:

Pouvez-vous essayer comme ceci:

{ 
    "query": { 
     "match_phrase": { 
      "MESSAGE": "UNH+66304" 
     } 
    } 
} 
+0

Si vous regardez mon premier exemple, vous verrez cela. Les autres exemples de code ont omis la première "requête" pour raccourcir le message (mais où encore utilisé dans le test). Vous pouvez avoir une "deuxième" "requête" si vous voulez en spécifier plus (par exemple l'opérateur). – Ben

1

Vous étiez sur la bonne voie de l'analyseur. Si vous regardez dans votre mappage de type, la propriété MESSAGE est probablement marquée comme analyzed. C'est pourquoi lors de l'indexation, il se débarrasse des caractères spéciaux. Vous devez le marquer comme not_analyzed.

Si vous nous faites savoir à quoi ressemble votre mappage de type, je peux vous aider avec le réglage correct.

Un des exemples -

Si votre version ES est < 5.0 et votre mappage de type ressemble à ceci -

{ 

    "MESSAGE": { 
    "type" "string", 
    "index": "analyzed" 
    } 
} 

changement à

{ 
    "MESSAGE": { 
    "type" "string", 
    "index": "not_analyzed" 
    } 
} 
+0

Merci pour la suggestion, j'utilise Elasticsearch 5.4 et il semble que l'API a changé et il y a beaucoup plus d'analyseurs à choisir à partir de maintenant. Je vais mettre à jour ma question concernant l'analyseur. – Ben

+0

Génial. Alors, ça marche maintenant? Si oui, je crois que vous pouvez répondre à votre propre question. Ça va être utile pour les autres. –