Analyzer pour une recherche partielle respectant l'ordre des mots


#1

Bonjour,

Je débute avec ElasticSearch (5.4) et je m’intéresse particulièrement aux analyzers.
Je cherche à faire une recherche qui peut être partielle mais dont l'ordre des mots à une importance.
Pour exemple, par rapport au document indexé ci-dessous :

PUT my_index/doc/1
{
  "description": "Recherchez (et analysez) vos données en temps réel."
} 

Si on cherche les chaînes de caractères "Recherchez (et" ou "rchez (e", par exemple, le document va être trouvé mais pour la chaîne "Recherchez et analysez (et" ou "Recherch (et" le document ne va pas être trouvé. La ponctuation est, elle aussi, importante.

Pour le moment, cette configuration m'a donné les meilleurs résultats :

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer",
          "filter": [
            "lowercase"
          ]
        },
        "my_analyzer_search": {
          "tokenizer": "keyword",
          "filter": "lowercase"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 8,
          "token_chars": [
            "letter",
            "digit",
            "punctuation",
            "symbol",
            "whitespace"
          ]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "description": {
          "type": "text",
          "analyzer": "my_analyzer",
          "search_analyzer": "my_analyzer_search"
        }
      }
    }
  }
}

J'utilise un analyzer pour l'indexation utilisant un tokenizer de type N-Gram pour la recherche partielle et, pour la recherche, un analyzer différent de type keyword pour l'ordre des mots.

Cependant mes documents pouvant être volumineux (jusqu'à une dizaine de Mo), cela demande beaucoup de ressources lors de l'indexation et la taille de l'index est énorme.
Est-ce tout de même une bonne solution ? Y-a t-il d'autres alternatives pour ce cas d'utilisation ?

Merci d'avance pour votre aide.


(David Pilato) #2

Tu pourrais éventuellement regarder du côté fuzzy search plutôt que de faire du ngram.

https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-fuzzy-query.html

Est-ce que ça t'aiderait ?

Pour l'ordre des mots, j'utiliserai une phrase search.

En combinant tout ça, tu peux influer sur l'ordre des résultats.

Ce script par exemple donne quelques exemples:


#3

Merci pour ta réponse et tes exemples. :slight_smile:

J'ai essayé avec le fuzziness et le match_phrase de la manière suivante :

GET my_index/_search
{
    "query": {
    "bool": {
      "should": [
                    {
          "match_phrase": {
            "comments": {
              "query" : "Who is that guy",
              "boost": 8.0
            }
          }
        },{
          "match": {
            "comments": {
              "query": "Who is that guy",
              "fuzziness": 2, 
              "boost": 2.0
            }
          }
        }  
        ]
    }
  }
}

Est-ce bien comme cela qu'il faut combiner les deux éléments ?

Cependant, par rapport à mon besoin, si le match_phrase ne match pas dans un document, le fuzziness peut trouver quand même des résultats mais il ne fera plus attention à l'ordre des mots dans ce cas non ?

J'ai aussi peur que le fuzziness trouve des mots totalement différents alors que je cherche plus des bouts de mots au final. Peut-être est-ce possible avec une recherche de type wildcard ?


(David Pilato) #4

Est-ce bien comme cela qu'il faut combiner les deux éléments ?

Oui.

mais il ne fera plus attention à l'ordre des mots dans ce cas non ?

Oui.

Je n'ai pas testé mais est-ce que tu peux faire aussi:

    {
      "match_phrase": {
        "comments": {
          "query" : "Who is that guy",
          "boost": 2.0,
          "fuzziness": "AUTO"
        }
      }
    }

Peut-être est-ce possible avec une recherche de type wildcard ?

Noooooooooooooooonnnnnn! Ne pas utiliser wildcard (sauf si ta vie en dépend) :wink:


#5

Ok je m'en souviendrai :smile:

J'ai testé le match_phrase avec le fuzziness mais visiblement la syntaxe n'est pas correcte j'ai le message suivant :

{
   "error": {
      "root_cause": [
         {
            "type": "parsing_exception",
            "reason": "[match_phrase] query does not support [fuzziness]",
            "line": 10,
            "col": 24
         }
      ],
      "type": "parsing_exception",
      "reason": "[match_phrase] query does not support [fuzziness]",
      "line": 10,
      "col": 24
   },
   "status": 400
}

(David Pilato) #6

Mouais. M'en doutais un peu.

Alors peut-être en utilisant des rqs très avancées comme les span queries... https://www.elastic.co/guide/en/elasticsearch/reference/5.5/span-queries.html

Mais peut-être que @jpountz ou @jimczi ont une autre idée ?


(system) #7

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.