[Résolu] Indexation des accents dans contenu HTML

cancel
Showing results for 
Search instead for 
Did you mean: 
sebguillomon
Member II

[Résolu] Indexation des accents dans contenu HTML

Bonjour,

Décidément, je vais de surprises en surprises avec Alfresco  :x, j'ai créé des contenu HTML dans Alfresco et j'ai testé la recherche via un webservice, mis-à part le fait que la recherche semble instable, je ne comprenais pas pourquoi je ne pouvais pas faire de recherche sur les mot avec des caractères accentués.
J'ai donc ouvert un index avec le jar lukeall (http://www.getopt.org/luke/) et à ma grande surprise, les caractères accentués semble être mal traités par l'analyseur lucene utilisé, par exemple pour rechercher le mot "crédit" (donc "crédit" en html); il faut faire une recherche sur "cr&eacute dit" car le point virgule est supprimé et le reste du mot n'est pas traité. !!!

Quelqu'un a-t-il une solution pour résoudre se problème? Peut-on surcharger le mécanisme d'indexation ?

Merci bcp
11 Replies
sebguillomon
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

Bonjour,

Après quelques heures de tuning, j'ai réussi à avoir une indexation convenable pour les contenu français (saisis via un du code html ou plein texte ou document …), j'ai donc modifié le fichier "dataTypeAnalyzers_fr.properties" comme suit :

d_dictionary.datatype.d_text.analyzer=alfresco.lucene.analysis.MonAnalyzer
#d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.fr.FrenchAnalyzer
d_dictionary.datatype.d_content.analyzer=alfresco.lucene.analysis.MonAnalyzer

avec MonAnalyzer :

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.ISOLatin1AccentFilter;
import org.apache.lucene.analysis.LowerCaseFilter;
import org.apache.lucene.analysis.PorterStemFilter;
import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.fr.FrenchAnalyzer;
import org.apache.lucene.analysis.fr.FrenchStemFilter;
import org.apache.lucene.analysis.standard.StandardFilter;
import org.apache.lucene.analysis.standard.StandardTokenizer;

public class MonAnalyzer extends Analyzer{

   private static Set _stopTable;
   private static Set _excltable;

    /**
     * An array containing some common English words
     * that are usually not useful for searching.
     */
    public static String[] STOP_WORDS = FrenchAnalyzer.FRENCH_STOP_WORDS;

    /**
     * Builds an analyzer.
     */
    public MonAnalyzer()
    {
        this(STOP_WORDS);
    }

    /**
     * Builds an analyzer with the given stop words.
     *
     * @param stopWords a String array of stop words
     */
    public MonAnalyzer(String[] stopWords)
    {       
        _stopTable = StopFilter.makeStopSet(STOP_WORDS);
    }

    /**
     * Processes the input by first converting it to
     * lower case, then by eliminating stop words, and
     * finally by performing Porter stemming on it.
     *
     * @param reader the Reader that
     *               provides access to the input text
     * @return an instance of TokenStream
     */
    public final TokenStream tokenStream(String fieldName, Reader reader)
    {
       if(fieldName == null)
            throw new IllegalArgumentException("fieldName must not be null");
        if(reader == null)
        {
            throw new IllegalArgumentException("reader must not be null");
        } else {
           Reader in = new HTMLStripReader(reader);
           StringBuffer htmlToText = new StringBuffer();
            int ch;
            try {
             while ( (ch=in.read()) != -1 ) {
                if ( ch != Character.MIN_VALUE )
                   htmlToText.append((char)ch);
             }
          } catch (IOException e) {
             throw new IllegalArgumentException("Error while reading html content");
          }
          
          ByteArrayInputStream bis = new ByteArrayInputStream(htmlToText.toString().getBytes());
           InputStreamReader isr = new InputStreamReader(bis);
          
            TokenStream result = new StandardTokenizer(isr);
            result = new StandardFilter(result);
            result = new FrenchStandardFilter(result);
            result = new StopFilter(result, _stopTable);
            result = new ISOLatin1AccentFilter(result);
            result = new FrenchStemFilter(result, _stopTable);
            result = new PorterStemFilter(result);
            result = new LowerCaseFilter(result);
           
            return result;
        }
    }
}

En ajoutant tous ces filtres cela fonctionne correctement.

- FrenchStandardFilter supprime les apostrophes
- ISOLatin1AccentFilter supprime les accents

HTMLStripReader permet de convertir le html en texte

Les autres sont des grands classiques  :wink:
superman
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

Bonjour,

ayant rencontré le même problème pour la recherche (accents et apostrophes);
j'ai lu avec intérêt ce sujet.

Malheureusement je ne connais pas le JAVA.

Bref;
j'essaye de comprendre le système….et après quelques nœuds au cerveau j'arrive à quelque chose.

Donc :
j'utilise votre code "MonAnalyzer"  (Grand merci)
je récupère lukeall.jar
je trouve les sources de HTMLStripReader et FrenchStandardFilter
(ouf….ça vas marcher….. :cry:  :cry: et non….)


C:\Documents and Settings\bp\Mes documents\NetBeansProjects\analyzerperso\src\alfresco\lucene\analysis\MonAnalyzer.java:90: cannot find symbol
symbol  : constructor FrenchStandardFilter(org.apache.lucene.analysis.TokenStream)
location: class fr.gouv.culture.sdx.search.lucene.analysis.filter.FrenchStandardFilter
            result = new FrenchStandardFilter(result);
C:\Documents and Settings\bp\Mes documents\NetBeansProjects\analyzerperso\src\fr\gouv\culture\sdx\search\lucene\analysis\filter\FrenchStandardFilter.java:53: cannot find symbol
symbol  : constructor TokenFilter()
location: class org.apache.lucene.analysis.TokenFilter
    public FrenchStandardFilter() {
2 errors


apparemment c'est une erreur de débutant….mais..
la j'y comprend plus rien….
Qu'est-ce que j'ais fait de travers??? :?:  :?:
PS:
j'ais JDK 1.6
et NetBeans
sebguillomon
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

Bonjour,

C'est assez, bizarre, c'est comme s'il s'agissait d'un pb de versions de classes et donc un constructeur non trouvé,
Voici le code de FrenchStandardFilter :

import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardTokenizerConstants;

/**
* A filter for special french words.
*/
public class FrenchStandardFilter extends TokenFilter implements StandardTokenizerConstants {

    /** Avalon super.getLog() to write information. */
    private org.apache.avalon.framework.logger.Logger logger;

    private static final String APOSTROPHE_TYPE = tokenImage[APOSTROPHE];
    private static final String ACRONYM_TYPE = tokenImage[ACRONYM];

    /**Builds a new filter
     *
     */
    public FrenchStandardFilter(TokenStream in) {
       super (in);
    }

    /**
     *   Builds a filter upon a token stream.
     *
     *   @param   in   The input token stream.
     */
    public void setUp(TokenStream in) {
        // Just keep track of the input stream.
        this.input = in;
    }

    /**
     * Returns the next token in the stream, or null at EOS.
     * <p>
     * Operations performed :
     * <ul>
     * <li>Removes l', d' in expressions such as l'&ecute;cole
     * <li>Remove dots from acronyms
     * </ul>
     */
    public Token next() throws java.io.IOException {
        Token t = input.next();
        if (t == null) return null;

        String text = t.termText();
        String type = t.type();

        if (type == APOSTROPHE_TYPE) {
            int idx = text.indexOf("'");
            if (idx < 2)  // Removes if the apostrophe is at beginning.
            {
                if (text.length() > idx + 3)
                    return new Token(text.substring(idx + 1), t.startOffset(), t.endOffset(), type);
                else
                    return t;
                // BUG: shoud return null, but with Lucene 1 all following words are deleted!
            } else
                return t;
        } else {
            if (type == ACRONYM_TYPE) {
                // Remove dots
                StringBuffer trimmed = new StringBuffer();
                for (int i = 0; i < text.length(); i++) {
                    char c = text.charAt(i);
                    if (c != '.') trimmed.append©;
                }
                return new Token(trimmed.toString(), t.startOffset(), t.endOffset(), type);
            } else
                return t;
        }
    }

}

Si ça ne fonctionne tjrs pas, n'hésitez pas à reposter un message et je vous donnerai mon mail pour que l'on échange.
superman
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

Merci beaucoup..ça marche maintenant.
j'ai pus compiler;
j'ai placé le jar dans "…\tomcat\webapps\alfresco\WEB-INF\lib"
j'ai fait les changement à "dataTypeAnalyzers_fr.properties"
et quand je relance le service; j'obtiens:…
2 sept. 2009 13:17:40 org.apache.catalina.core.ApplicationContext log
INFO: Set web app root system property: 'webapp.root' = [e:\Intranet\tomcat\webapps\alfresco\]
2 sept. 2009 13:17:40 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
2 sept. 2009 13:18:05 org.apache.catalina.core.StandardContext listenerStart
GRAVE: Exception lors de l'envoi de l'�v�nement contexte initialis� (context initialized) � l'instance de classe d'�coute (listener) org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptDebugger' defined in class path resource [alfresco/webscript-framework-application-context.xml]: Instantiation of bean failed; nested exception is java.lang.IllegalAccessError: class org.alfresco.web.scripts.AlfrescoScriptDebugger$AlfrescoGui cannot access its superclass org.mozilla.javascript.tools.debugger.SwingGui
Caused by: java.lang.IllegalAccessError: class org.alfresco.web.scripts.AlfrescoScriptDebugger$AlfrescoGui cannot access its superclass org.mozilla.javascript.tools.debugger.SwingGui
   at java.lang.ClassLoader.defineClass1(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
   at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1847)
   at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:890)
   at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
   at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
   at java.lang.Class.getDeclaredConstructors0(Native Method)
   at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
   at java.lang.Class.getConstructor0(Class.java:2699)
   at java.lang.Class.getDeclaredConstructor(Class.java:1985)
   at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:54)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:756)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:721)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:384)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
   at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:244)
   at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:187)
   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
   at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:830)
   at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:719)
   at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:490)
   at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
   at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
   at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
   at org.apache.catalina.core.StandardService.start(StandardService.java:516)
   at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
   at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
2 sept. 2009 13:18:05 org.apache.catalina.core.StandardContext listenerStart
GRAVE: Exception lors de l'envoi de l'�v�nement contexte initialis� (context initialized) � l'instance de classe d'�coute (listener) org.alfresco.web.app.ContextListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptDebugger' defined in class path resource [alfresco/webscript-framework-application-context.xml]: Instantiation of bean failed; nested exception is java.lang.IllegalAccessError: class org.alfresco.web.scripts.AlfrescoScriptDebugger$AlfrescoGui cannot access its superclass org.mozilla.javascript.tools.debugger.SwingGui
Caused by: java.lang.IllegalAccessError: class org.alfresco.web.scripts.AlfrescoScriptDebugger$AlfrescoGui cannot access its superclass org.mozilla.javascript.tools.debugger.SwingGui
   at java.lang.ClassLoader.defineClass1(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
   at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1847)
   at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:890)
   at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
   at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
   at java.lang.Class.getDeclaredConstructors0(Native Method)
   at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
   at java.lang.Class.getConstructor0(Class.java:2699)
   at java.lang.Class.getDeclaredConstructor(Class.java:1985)
   at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:54)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:756)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:721)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:384)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
   at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:244)
   at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:187)
   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
   at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:830)
   at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:719)
   at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:490)
   at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
   at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
   at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
   at org.apache.catalina.core.StandardService.start(StandardService.java:516)
   at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
   at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
2 sept. 2009 13:18:05 org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
2 sept. 2009 13:18:05 org.apache.catalina.core.ApplicationContext log
INFO: Shutting down Log4J
2 sept. 2009 13:18:08 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
2 sept. 2009 13:18:13 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
2 sept. 2009 13:19:16 org.apache.catalina.core.ApplicationContext log
INFO: org.tuckey.web.filters.urlrewrite.utils.Log ERROR: logLevelConf: null
2 sept. 2009 13:19:16 org.apache.catalina.core.ApplicationContext log
INFO: org.tuckey.web.filters.urlrewrite.UrlRewriteFilter INFO: loaded (conf ok)
2 sept. 2009 13:19:16 org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
2 sept. 2009 13:19:16 org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
:cry:  :cry:
en lisant le log j'ai l'impression que l'erreur ne viens pas de ce que j'ai fait…
Smiley Surprisedops:  Smiley Surprisedops: Pourtant c'est sûrement le cas.. :wink:  Smiley Surprisedops:
sebguillomon
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

A priori rien à voir avec cette customisation…

Alfresco démarre-t-il malgré cette erreur? si oui, l'indexation est-elle correcte ?
superman
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

Alfresco ne démarre pas….
Il faut que je supprime les JAR que j'avais ajouté dans "…\tomcat\webapps\alfresco\WEB-INF\lib"   (analiseperso.jar et lukeall.jar) pour redémarrer le service…..

Faut-il déclarer quelque part l'ajour d'un JAR :?:  :?:
jayjayecl
Active Member II

Re: [Résolu] Indexation des accents dans contenu HTML

just lukeall.jar devrait suffire

sinon, lukeall.jar, on s'en sert, en fait, en double-cliquant dessus, comme un .exe Smiley Wink
sebguillomon
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

perso, j'ai ajouté l'analyser et les filtres dans mon jar mais je n'ai pas mis lukeall.jar dans web-inf/lib, il faut mettre juste son jar perso dedans

Lukeall permet juste de visualiser un index pour voir le résultat de l'indexation
superman
Member II

Re: [Résolu] Indexation des accents dans contenu HTML

ça y est….. :!:  :!:
ça marche :!:  :!:

Par contre faut-il faire quelque chose pour ré-indexer la base??
Car la recherche se comporte de la même manière.. :?  :?