[Résolu]rechercher avec lucene et java dans un seul document

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

[Résolu]rechercher avec lucene et java dans un seul document

bonjour a tous,
voila je suis en train de faire une classe qui recherche dans un nœud un ou des mots et retourne true ou false.
le paramètre d'entrée "tags" est composé de mots  séparé par des virgule sous la forme "toto,+tata" sachant que le '+' donne un caractère obligatoire a ce mot.

les test avec simplement la valeur "ID" du nœud me trouve bien le nœud concerné.

           String queryOut="+ID:\""+ nodeRef.toString()+"\" ";

le test avec la série de mots me trouve bien les nœud qui contienne ces mots suivant leurs contraintes.

   query = query + " TEXT:\"+"+chktg.trim()+"\" ";
inconvénient je recherche sur tous les nœuds du repository.

Mais quand je combine les deux avec "AND" ceci me donne toujours faux.
car il ne trouve plus le nœud défini par l'"ID"


   public static boolean searchInNodeRef(NodeRef nodeRef, String tags, NodeService nodeService, SearchService searchService ) {

      boolean returned=false;
      ContentData contentData = (ContentData) nodeService.getProperty(nodeRef,ContentModel.PROP_CONTENT);
      Locale locale = contentData.getLocale();
      SearchParameters searchParameters= new SearchParameters();
      searchParameters.setLanguage(SearchService.LANGUAGE_LUCENE);
      searchParameters.addStore(nodeRef.getStoreRef());
      if (locale != null ) {
         searchParameters.addLocale(locale);
      }

           String queryOut="+ID:\""+ nodeRef.toString()+"\" ";

      String query="";
      
      if (tags == null || tags.length() <= 0) {
         return returned;
      }
      String tagsAnd = "";
      String tagsOr = "";
        
      StringTokenizer tokenizer = new StringTokenizer(tags, ",");
      while (tokenizer.hasMoreTokens()) {
            String chktg=tokenizer.nextToken();
            if ( chktg.substring(0, 1).compareTo("+") == 0 )  {
               tagsAnd = tagsAnd + chktg.substring(1, chktg.length()) + " ";
            } else {
               tagsOr = tagsOr + chktg + " ";              
            }
      }
        
      if ( tagsAnd.length() > 0 ) {
            tokenizer = new StringTokenizer(tagsAnd, " ");
            while (tokenizer.hasMoreTokens()) {
               String chktg=tokenizer.nextToken();
               query = query + " TEXT:\"+"+chktg.trim()+"\" ";
            }
      }

      if ( tagsOr.length() > 0 ) {
         query = query + " +( ";
         tokenizer = new StringTokenizer(tagsOr, " ");
        
         while (tokenizer.hasMoreTokens()) {
            String chktg=tokenizer.nextToken();
            query = query + " TEXT:\""+chktg.trim()+"\" ";
         }
         query = query + " )";
      }

      queryOut= queryOut + " " + query.trim();
      searchParameters.setQuery( queryOut.trim() );           
      // Transform the results into a node list
      ResultSet results = null;
      try {
         results = searchService.query(searchParameters);
         for (ResultSetRow row : results) {
            if (nodeRef.getId().compareTo(row.getNodeRef().getId()) == 0) {
               returned = true;  
            }
         }
      }
      finally {
         if (results != null) {
            results.close();
         }
      }
      return returned;
   }

merci d'avance pour vos Idées

Vincent
6 Replies
rguinot
Customer

Re: [Résolu]rechercher avec lucene et java dans un seul document

Tout ceci n'est pas très clair .
que cherchez vous à faire exactement (indépendamment de l'implémentation).

D'autre part vous ne précisez pas votre environnment de déploiement …
adnuser
Member II

Re: [Résolu]rechercher avec lucene et java dans un seul document

la classe ci-dessus doit répondre true ou false si on trouve des mots ( obligatoire ou pas ) dans le noderef en arguments.
je précise que ceci est fait avec une classe dérivé de ActionExecuterAbstractBase dans la fonction executeImpl.

mon environnement est classique :
RedHat + tomcat 6.0 + java 1.6 + mysql 4

merci de votre réponse.
rivarola
Active Member

Re: [Résolu]rechercher avec lucene et java dans un seul document

Bonjour,

Tu as essayé de tester ta requête combinant ID et TEXT directement dans le NodeBrowser ?
De mon côté je remonte bien des docs quand j'essaie de combiner ces deux clauses (sur Alfresco 2.2E).
Si ID ne marche pas comme attendu, tu peux toujours utiliser sys:node-uuid à la place :
@sys\:node-uuid:(fef01cce-7dbe-11dd-b66d-db7edbe1ff00)
adnuser
Member II

Re: [Résolu]rechercher avec lucene et java dans un seul document

Tu as essayé de tester ta requête combinant ID et TEXT directement dans le NodeBrowser ?
oui mais je me suis apperçu que le document qui arrive dans un workflow n'est pas encore indexé … donc pas de recherche Smiley Sad

je pense creer un index temporaire avec lucene pour simplement rechercher des valeurs dedans…

Si ID ne marche pas comme attendu, tu peux toujours utiliser sys:node-uuid à la place :
@sys\:node-uuid:(fef01cce-7dbe-11dd-b66d-db7edbe1ff00)
déja testé , même effet …

Je cherche a faire un module qui fait des règles de workflow avec une recherche sur des mots ex:
le document1 contient le mot facture je le met dans l'espace factures.

je trouve cela étrange que alfresco n'as pas mis cette action par défaut dans le war ?

vincent
rivarola
Active Member

Re: [Résolu]rechercher avec lucene et java dans un seul document

Bonjour,

oui mais je me suis apperçu que le document qui arrive dans un workflow n'est pas encore indexé … donc pas de recherche Smiley Sad

C'est une règle qui lance le workflow ? Si c'est le cas, as-tu essayé de la lancer en tache de fond ?
adnuser
Member II

Re: [Résolu]rechercher avec lucene et java dans un seul document

Résolu,
en fait je creer un lucene en ram seulement pour ce que je cherche :
ex:


import java.io.StringReader;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.queryParser.QueryParser;

public class LuceneSearcher {
   private String ID;
   private Directory indexDirectory;
   
   /**
    *
    * @param workingNode
    * @throws Exception
    */
   public LuceneSearcher(NodeRef workingNode ,ReaderString readerText ) throws Exception {
      

      this.indexDirectory = new RAMDirectory();

      IndexWriter writer = new IndexWriter(this.indexDirectory, getAnalyzer(), true);
        Document doc = new Document();
       
        Field idField = new Field("ID", workingNode.getId());
        doc.add(idField);
        this.ID=workingNode.getId();
       
        Field textField = new Field("TEXT", readerText);
        doc.add(textField);
       
        writer.addDocument(doc);
        writer.close();
   }

   protected Analyzer getAnalyzer() {
      return new StandardAnalyzer();
   }
   
   public boolean searchInDocument(String values ) throws Exception {
      IndexReader reader = IndexReader.open(this.indexDirectory);
       TopDocCollector collector = new TopDocCollector(100);
       Searcher searcher = new IndexSearcher(reader);
       Analyzer analyzer = getAnalyzer();
       String field = "ID";
       QueryParser parser = new QueryParser(field, analyzer);
            String queryValue="ID:\""+this.ID+"\";
             queryValue=queryValue+" AND ";
             queryValue=queryValue+" ( ";
             queryValue=queryValue+" TEXT:"+values;
             queryValue=queryValue+" ) ";
       Query query = parser.parse(queryValue);

       searcher.search(query, collector);
       ScoreDoc[] hits = collector.topDocs().scoreDocs;
       searcher.close();
       if ( hits.length > 0 )
          return true;
       return false;
   }
}

pour l'utiliser c'est simple:
LuceneSearcher luceneSearcher= new LuceneSearcher(NodeRef <la reference du noeud a verifier>, <un ReaderString du contenu> );

ensuite on verifie avec un boolean:
boolean result = luceneSearcher.searchInDocument(String <la recherche sans espace> );


vincent