Un bon analyzer francais

1,990 views
Skip to first unread message

Rémi Montagu

unread,
Mar 14, 2012, 6:42:43 AM3/14/12
to elastics...@googlegroups.com
Bonjour,

J'ai besoin d'un meilleur analyzer que le french de base de ES.
J'ai tester d'autres analyzers (http://dev.af83.com/2012/01/13/tire-pour-les-francophones.html) sans plus de réussite.
https://gist.github.com/2035631

Avec cette configuration:
- le term "prix" retourne bien le document
- le term "essence" ne retourne rien
- le term "litre" ne retourne rien
- le term "distributeurs" ne retourne rien
- le trem "distributeur" ne retourne rien
- le trem "distributeur*" retourne le document et highlight "distributeurs" -_-
- le term "président" retourne bien le document
- le term "présidents" retourne bien le document
- le term "Présidents" retourne bien le document
- le term "Président" retourne bien le document

Est-ce un problème de la requête? de l'analyzer?
Merci de votre aide.

da...@pilato.fr

unread,
Mar 14, 2012, 11:39:15 AM3/14/12
to elastics...@googlegroups.com

Salut Rémi,

 

 

Est-ce que tu as essayé de voir comment ton document avait été découpé par ES ?

Une commande du genre :

curl -XGET 'localhost:9200/_analyze?analyzer=french' -d @input.json

 

Par ailleurs, je ne connais pas cette syntaxe :

     '_analyzer' : {
         'path' : 'french'
     }
Ca veut dire que tu appliques un analyzer différent pour chaque document au moment de l'indexation plutôt que de définir un mapping pour les champs title et message ?

 

Du coup, quel est ton mapping pour le type de ton document ? Il n'y en a pas ?

 

 

David. 


Le 14 mars 2012 à 11:42, "Rémi Montagu" <d...@amanager.net> a écrit :

Bonjour,

J'ai besoin d'un meilleur analyzer que le french de base de ES.
J'ai tester d'autres analyzers ( http://dev.af83.com/2012/01/13/tire-pour-les-francophones.html ) sans plus de réussite.
https://gist.github.com/2035631

Avec cette configuration:
- le term "prix" retourne bien le document
- le term "essence" ne retourne rien
- le term "litre" ne retourne rien
- le term "distributeurs" ne retourne rien
- le trem "distributeur" ne retourne rien
- le trem "distributeur*" retourne le document et highlight "distributeurs" -_-
- le term "président" retourne bien le document
- le term "présidents" retourne bien le document
- le term "Présidents" retourne bien le document
- le term "Président" retourne bien le document

Est-ce un problème de la requête? de l'analyzer?
Merci de votre aide.

 

--
---
Vous pouvez également poster et consulter les réponses en anglais sur le groupe Elasticsearch https://groups.google.com/group/elasticsearch
 
Si vous avez également posté votre question sur la mailing list elasti...@googlegroups.com, merci d'indiquer ici le lien vers cette discussion pour faciliter le suivi.
 
Twitter : @ElasticsearchFR https://twitter.com/#!/ElasticsearchFR
Site web (English) : http://www.elasticsearch.org/

 


--
David Pilato
http://dev.david.pilato.fr/
Twitter : @dadoonet

Rémi Montagu

unread,
Mar 15, 2012, 3:22:23 AM3/15/12
to elastics...@googlegroups.com, da...@pilato.fr
Merci de ta réponse David.

J'ai déjà essayé d'analyzer mon document en utilisant _analyze. Les mots qui ne ressortent pas de documents précédemments y sont analyzer comme il le devrait.
prix => prix
essence => essenc
litre => litr
distributeurs => distributeur
distributeur => distributeur
président => président
Président => président
Cet analyzer a un problème avec les accents principalement.

Pour la syntaxe de l'analyzer, je l'ai trouvé sur le group anglais (https://groups.google.com/d/topic/elasticsearch/3LvuC3Ng4wk/discussion). Ils font référence a cet article de la doc (http://www.elasticsearch.org/guide/reference/mapping/analyzer-field.html). Je l'ai peut être mal utilisé.
J'utilise cette syntaxe parce que dans mon projet j'ai des documents en anglais, en francais, en espagnol, peut être de l'arabe.
Est-ce que j'ai mal compris?

Le mapping est celui de base. Je n'ai rien changé pour cet index.

Rémi Montagu

unread,
Mar 15, 2012, 3:51:07 AM3/15/12
to elastics...@googlegroups.com, da...@pilato.fr
Je vais me répondre. La syntaxe n'est pas la bonne en fait.
Je vais essayer de faire un index par langue avec le bon mapping en default et voir ce que ça donne.

David

unread,
Mar 21, 2012, 6:33:19 AM3/21/12
to Elasticsearch FR
Salut Rémi,


Je pense avoir trouvé une configuration assez bonne pour le français.
J'ai fait un GIST ici : https://gist.github.com/2146038

Tu verras qu'avec cette config, tu peux chercher aussi bien des mots
comme "essence", "président" ou "president".

Je viens d'appliquer ça sur mon projet pro et ça fonctionne plutôt
bien.

A noter la "bidouille" sur l'analyzer à appliquer au champ _all.
En effet, comme tu ne précises pas dans la query sur quels champs tu
bosses, ES va utiliser _all par défaut. Du coup, il applique à ta
query, l'analyzer défini pour _all. Si tu n'en mets pas, le mot
president ne sera pas trouvé car ES a indexé président dans le champ
_all.

L'autre solution est également de conserver _all avec son traitement
par défaut ou de ne pas inclure _all et de préciser les champs exacts
de ta recherche :

curl -XPOST $ES/$ESIDX/$ESTYPE/_search?pretty=true -d '{
"query": {
"query_string": {
"fields" : [ "message" ],
"query" : "president"
}
}
}'

Dans ce cas, le mapping peut être :
curl -XPUT $ES/$ESIDX/$ESTYPE/_mapping -d '{
"test" : {
"properties" : {
"title" : {"type" : "string", "analyzer":"francais"},
"message" : {"type" : "string", "analyzer":"francais"}
}
}
}'

En espérant que cela t'aide,
David.

On 14 mar, 11:42, Rémi Montagu <d...@amanager.net> wrote:
> Bonjour,
>
> J'ai besoin d'un meilleur analyzer que le french de base de ES.
> J'ai tester d'autres analyzers (http://dev.af83.com/2012/01/13/tire-pour-les-francophones.html) sans plus
> de réussite.https://gist.github.com/2035631

Rémi Montagu

unread,
Mar 21, 2012, 8:43:18 AM3/21/12
to elastics...@googlegroups.com
Merci de ta réponse David.

J'été en train d'y travailler ce matin. Je suis arrivé a presque la même solution que toi.

curl -XPUT 'localhost:9200/fr/_settings' -d '{
    "index.analysis.analyzer.default.type": "custom",
    "index.analysis.analyzer.default.tokenizer": "standard",
    "index.analysis.analyzer.default.filter.0": "lowercase",
    "index.analysis.analyzer.default.filter.1": "asciifolding",
    "index.analysis.analyzer.default.filter.2": "my_stop",
    "index.analysis.analyzer.default.filter.3": "elision",
    "index.analysis.analyzer.default.filter.4": "my_snowball",
    "index.analysis.filter.my_stop.type": "stop",
    "index.analysis.filter.my_stop.stopwords": "french",
    "index.analysis.filter.my_snowball.type": "snowball",
    "index.analysis.filter.my_snowball.language": "French"
}'

Merci d'avoir pris le temps de répondre.

Fabien Chung

unread,
Jul 26, 2013, 12:18:23 PM7/26/13
to elastics...@googlegroups.com
Bonjour,

Nous sommes actuellement en train de tester l'analyzer beider-morse posté par David. Mais justement nous rencontrons un problème, notre use case serait de chercher sur tous les champs, mais avec un seul qui serait avec cet analyzer phonetique.
Voici notre mapping :

{

"settings" : {
       "index" : {
          "analysis" : {
             "filter" : {
                "beider_morse": {
                    "type" : "phonetic",
                    "encoder" : "beider_morse",
                    "languageset" : [ "french"]
                }
             },
             "analyzer" : {
                "phoneticAnalyzer" : {
                    "type" : "custom",
                    "tokenizer" : "standard",
                    "filter" : ["standard", "lowercase", "stemmer", "beider_morse"]
                }
             }
          }
       }        
    },





"mappings" : {
    "vente" : {
      "properties" : {
        "numvente" : {
          "type" : "integer"
        },
        "numlignvente" : {
          "type" : "integer"
    

        },
        "produit" : {
          "type" : "string"
    
        },
        "prixunitaire" : {
          "type" : "float"

        },
        "qte" : {
          "type" : "integer"

        },
        "vendeur" : {
          "type" : "string"

        },
"numtel": {
"type" : "string"
},
        "rayon" : {
          "type" : "string",
  "index": "analyzed",
  "analyzer" : "phoneticAnalyzer"

        },
        "magasin" : {
          "type" : "string"

        }, 
        "region" : {
          "type" : "string"

        },
        "date": {
        "type" : "date",
"index" : "not_analyzed",
        "format":"yyyyMMdd HH:mm"

        }                                             
      }
   
  }
}
}

Cette requêtte ne renvoie rien :

{
    
  "query": {
 "filtered": {
     "query": {
       "query_string":{
         "query": "elektro",
      "analyzer":  "phoneticAnalyzer"
       }
     },
     "filter": {
       "match_all": {}
       
     }
   }
  
  
  },
  "facets": {
   
    "parRayon": {
      "terms": {
        "field": "rayon"
      }
    },
    "parAnnee":{
            "date_histogram": {
               "field": "date",
               "interval": "year"
            }
    }
  }
  
  
  
}


Par contre celle-ci oui :

{
    "query" : {
        "text": {
             "rayon": {
                 "query": "helektrauh"
             }
        }
    }
}


Quel est la meilleure stratégie a adopter pour pouvoir faire une recherche sur tous les champs mais un un seul uniquement l'analyzer ? 

Cordialement,
 

Le mercredi 21 mars 2012 11:33:19 UTC+1, David a écrit :

Jérôme Mainaud

unread,
Jul 27, 2013, 11:25:09 AM7/27/13
to elastics...@googlegroups.com
Bonjour,

Dans ton cas, la meilleure stratégie est d'utiliser le champ _all pour tous les champs sauf ton champ "rayon". Pour cela, dans ton mapping, tu l'exclus de _all avec l'option "include_in_all" : false. Ensuite lors de tes recherches, tu cherches en même temps sur "_all" et sur "rayon".

Bon weekend.

Jérôme Mainaud
jer...@mainaud.com
Le 26/07/13 18:18, Fabien Chung a écrit :
--
--
---
Vous pouvez également poster et consulter les réponses en anglais sur le groupe Elasticsearch https://groups.google.com/group/elasticsearch
 
Si vous avez également posté votre question sur la mailing list elasti...@googlegroups.com, merci d'indiquer ici le lien vers cette discussion pour faciliter le suivi.
 
Twitter : @ElasticsearchFR https://twitter.com/#!/ElasticsearchFR
Site web (English) : http://www.elasticsearch.org/
 
---
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Elasticsearch FR.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse elasticsearch-...@googlegroups.com.
Pour plus d'options, visitez le site https://groups.google.com/groups/opt_out .
 
 

Aymeric MARTIN

unread,
Jul 29, 2013, 4:17:33 AM7/29/13
to elastics...@googlegroups.com
Bonjour Jérôme,

Merci pour ta réponse (je travaille sur le même sujet que Fabien).
Ta solution semble très bonne, en revanche je n'arrive pas à la mettre en oeuvre. J'ai bien exclus le rayon de "_all" dans le mapping, mais je ne sais pas comment rechercher en même temps dans "_all" et "rayon" dans la query.

Si je rajoute "default_field" : "rayon"  dans ma query_string, il recherche bien dans rayon mais plus dans "_all". Saurais tu comment faire?

Je mets le nouveau mapping ainsi que la query à la suite.
Merci



Mapping
{
   "vente": {
      "properties": {
         "date": {
            "type": "date",
            "format": "yyyyMMdd HH:mm",
            "include_in_all": true
         },
         "magasin": {
            "type": "string",
            "include_in_all": true
         },
         "numlignvente": {
            "type": "integer",
            "include_in_all": true
         },
         "numtel": {
            "type": "string",
            "include_in_all": true
         },
         "numvente": {
            "type": "integer",
            "include_in_all": true
         },
         "prixunitaire": {
            "type": "float",
            "include_in_all": true
         },
         "produit": {
            "type": "string",
            "include_in_all": true
         },
         "qte": {
            "type": "integer",
            "include_in_all": true
         },
         "rayon": {
            "type": "string",
            "analyzer": "phoneticAnalyzer",
            "include_in_all": false
         },
         "region": {
            "type": "string",
            "include_in_all": true
         },
         "vendeur": {
            "type": "string",
            "include_in_all": true
         }
      }
   }
}




Query:

{
    
  "query": {
 "filtered": {
     "query": {
       "query_string":{
         "query": "*helektrau*",
         "default_field": "rayon", 

Aymeric MARTIN

unread,
Jul 29, 2013, 4:41:47 AM7/29/13
to elastics...@googlegroups.com
Je me réponds à moi-même, il sufffit de rajouter "fields" dans la query_string.


"query_string":{
         "query": "ma query",
         "fields": [
            "rayon","_all"
         ],


En revanche, notre use case veut que nous utilisions des * dans la query, et l'analyzer n'a pas l'air d'aimer...
Ainsi si je cherche "helektrau", les ventes du rayon electro sont bien remontées, mais si je cherche "*helektrau*", plus rien n'est remonté...
Une idée? 

Merci,

Aymeric

Jérôme Mainaud

unread,
Jul 29, 2013, 7:44:04 AM7/29/13
to elastics...@googlegroups.com
Bonjour,

Les "*" sont transformées en requêtes de type Wildcard qui n'utilisent pas les analyseurs.
Il cherchera donc les termes qui contiennent "helektrau".

Mon avis perso : il faut fuir ce type de requêtes qui sont lentes, surtout si tu places une étoile en début de terme, et utiliser le filtre ngram.

Je pense que le ngram sera compatible avec la phonétisation, à quelques effets prêts. Par exemple, "électronique" sera surement trouvé à partie de "electo" et "electroni", mais pas à partir de "electron". Ces effets peuvent être atténuer, voir supprimé par une recherche en parallèle sur la forme exacte.

Bonne journée.


--
Jérôme Mainaud
jer...@mainaud.com
Reply all
Reply to author
Forward
0 new messages