158 votes

Comment rechercher une partie d'un mot avec ElasticSearch

J'ai récemment commencé à utiliser ElasticSearch et je n'arrive pas à faire en sorte qu'il recherche une partie d'un mot.

Exemple : J'ai trois documents de mon couchdb indexés dans ElasticSearch :

{
  "_id" : "1",
  "name" : "John Doeman",
  "function" : "Janitor"
}
{
  "_id" : "2",
  "name" : "Jane Doewoman",
  "function" : "Teacher"
}
{
  "_id" : "3",
  "name" : "Jimmy Jackal",
  "function" : "Student"
} 

Donc maintenant, je veux rechercher tous les documents contenant "Doe".

curl http://localhost:9200/my_idx/my_type/_search?q=Doe

Cela ne renvoie aucun résultat. Mais si je cherche

curl http://localhost:9200/my_idx/my_type/_search?q=Doeman

Elle renvoie un document (John Doeman).

J'ai essayé de définir différents analyseurs et différents filtres comme propriétés de mon index. J'ai également essayé d'utiliser une requête complète (par exemple :

{
  "query": {
    "term": {
      "name": "Doe"
    }
  }
}

) Mais rien ne semble fonctionner.

Comment faire pour qu'ElasticSearch trouve à la fois John Doeman et Jane Doewoman lorsque je recherche "Doe" ?

UPDATE

J'ai essayé d'utiliser le tokenizer et le filtre nGram, comme Igor l'a proposé, comme ceci :

{
  "index": {
    "index": "my_idx",
    "type": "my_type",
    "bulk_size": "100",
    "bulk_timeout": "10ms",
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "tokenizer": "my_ngram_tokenizer",
          "filter": [
            "my_ngram_filter"
          ]
        }
      },
      "filter": {
        "my_ngram_filter": {
          "type": "nGram",
          "min_gram": 1,
          "max_gram": 1
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "type": "nGram",
          "min_gram": 1,
          "max_gram": 1
        }
      }
    }
  }
}

Le problème que je rencontre actuellement est que chaque requête renvoie TOUS les documents. Des pistes ? La documentation d'ElasticSearch sur l'utilisation de nGram n'est pas très bonne...

10 votes

Pas étonnant, vous habe min/max ngram réglé sur 1, donc 1 lettre :)

3 votes

Je suis en fait surpris que l'ES ne rende pas cela plus facile. C'est ElasticSearch, pas ElasticExactMatchUnlessIDoSomeCeremony.

-4voto

ldx Points 560

Jamais de la vie.

J'ai dû regarder la documentation de Lucene. Il semble que je puisse utiliser des jokers ! :-)

curl http://localhost:9200/my_idx/my_type/_search?q=*Doe*

fait l'affaire !

11 votes

Voir la réponse de @imotov. L'utilisation de caractères génériques ne sera pas du tout adaptée.

5 votes

@Idx - Voyez comment votre propre réponse est rétrogradée. Les downvotes représentent la qualité et la pertinence d'une réponse. Pourriez-vous prendre une minute pour accepter la bonne réponse ? Au moins, les nouveaux utilisateurs vous en seront reconnaissants.

3 votes

Assez de votes négatifs. L'OP a clairement indiqué quelle est la meilleure réponse maintenant. +1 pour avoir partagé ce qui semblait être la meilleure réponse avant que quelqu'un en poste une meilleure.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X