Web Service : requête lucene Limitée à 1000 résultats

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

Web Service : requête lucene Limitée à 1000 résultats

Je développe un petit programme d'export Alfresco qui recherche des documents et crée un fichier csv avec les méta-données des documents.
Pour éliminer les différents timeout Alfresco, JBoss et Axis je modifie (temporairement) les fichiers :
+ custom-repository.properties : system.acl.maxPermissionCheckTimeMillis=2000000 ; system.acl.maxPermissionChecks=200000 ; lucene.query.maxClauses=2000000 ; lucene.maxAtomicTransformationTime=4000 ; lucene.write.lock.timeout=2000000 ; lucene.commit.lock.timeout= 20000000
+ jboss-service.xml : <attribute name="SocketTimeout">6000000</attribute>
+ server.xml : <Connector port="8080" address="${jboss.bind.address}" maxThreads="250" strategy="ms" maxHttpHeaderSize="8192" emptySessionPath="true" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="2000000" disableUploadTimeout="true"/>
+ Et le timeout Axis dans le code : repositoryService.setTimeout(timeout); (private static final int timeout = 50000000; )

Maintenant, il n'y a plus d'erreur mais le CSV généré ne contient que 1000 lignes (alors qu'il il y a 40 000 documents dans la base).
Voici le code source utilisé :

FileCSV myCSV = new FileCSV (export.getDestinationFile());
Query query = new Query(Constants.QUERY_LANG_LUCENE, requete);                              
QueryResult result = getRepositoryService().query(store, query, true);

if (result != null && result.getResultSet() != null) {              
   ResultSetRow[] rows = result.getResultSet().getRows();              
   if (rows == null ||  rows.length == 0) {
      System.out.println("AUCUN document trouvé par la requete !!");
      myCSV.close();
      return;
   } else
      System.out.println("Nombre de documents trouvés par la requete : " + String.valueOf(rows.length));
   
   // Pour chaque resultat = node
   for (int i = 0; i < rows.length ; ++i) {
      NamedValue[] props = rows[i].getColumns();
      List<Column> columns = export.getColumns();


J'aurais bien voulu utiliser "LimitBy limitBy = resultSet.getResultSetMetaData().getLimitedBy();" (http://forums.alfresco.com/en/viewtopic.php?f=6&t=13381) mais visiblement, cette méthode n'est utilisable que pour les API et pas les Web services.
Merci par avance si quelqu'un a une solution.
6 Replies
laurentprad
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Bonjour,
J'ai maintenant trouvé un moyen de "découper" les résultats pour éviter cette limite de 1000 en utilisant "setFetchSize" :

// set the batch size in the query header
int batchSize = 500;
QueryConfiguration queryCfg = new QueryConfiguration();
queryCfg.setFetchSize(batchSize);
RepositoryServiceSoapBindingStub repositoryService = WebServiceFactory.getRepositoryService();
repositoryService.setHeader(new RepositoryServiceLocator().getServiceName().getNamespaceURI(), "QueryHeader", queryCfg);

// Propietes de repository service (la fonction getRepositoryService() ne doit plus être utilisée car elle ne prend pas le Header)
repositoryService.setUsername(username);
repositoryService.setPassword(password);
repositoryService.setTimeout(timeout);

Query query = new Query(Constants.QUERY_LANG_LUCENE, requete);

//  get the first batch of results          
QueryResult result = repositoryService.query(store, query, true);

// Write the first lines (process the first query result) :
writeLines(result, myCSV, export);

// Look for next lines (process the next query results) :
String querySession = result.getQuerySession();
while (querySession != null) {
//  get the next batch of results
   result = repositoryService.fetchMore(querySession);
   
   // Write the next lines :
   writeLines(result, myCSV, export);

   // process subsequent query results
   querySession = result.getQuerySession();   
}             

Sauf que lorsque je le lance sur une base conenant beaucoup d'éléments, j'obtiens :
requete Lucene : @cm\:name:*pdf AND @cm\:name:BD_01* AND PATH:"/app:company_home/cm:MYPATH//*" AND @cm\:created:[2007\-09\-01T00:00:00 TO 2008\-09\-30T00:00:00]
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString:
faultActor:
faultNode:
faultDetail:
        {http://www.alfresco.org/ws/service/repository/1.0}RepositoryFault:<ns1:errorCode>                                                                                                         0</ns1:errorCode><ns1:message>org.alfresco.error.AlfrescoRuntimeException: Exception in Tr                                                                                                         ansaction.</ns1:message>
        {http://xml.apache.org/axis/}exceptionName:org.alfresco.repo.webservice.repository                                                                                                         .RepositoryFault
        {http://xml.apache.org/axis/}stackTrace:
        at org.alfresco.repo.webservice.repository.RepositoryWebService.executeQuery(Repos                                                                                                         itoryWebService.java:176)
        at org.alfresco.repo.webservice.repository.RepositoryWebService.query(RepositoryWe                                                                                                         bService.java:195)
        at sun.reflect.GeneratedMethodAccessor473.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja

Quelqu'un pourrait-il m'aider ?  Smiley Sad
wadael
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Bonjour,

As-tu d'autres traces ? (c'est un peu court)

Il va te falloir regarder les sources, notamment RepositoryWebService.java ligne 176
laurentprad
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Bonjour, et merci pour ta réponse  :wink:
Voici donc la trace complète :

AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString:
faultActor:
faultNode:
faultDetail:
        {http://www.alfresco.org/ws/service/repository/1.0}RepositoryFault:<ns1:errorCode>                                                                                                         0</ns1:errorCode><ns1:message>org.alfresco.error.AlfrescoRuntimeException: Exception in Tr                                                                                                         ansaction.</ns1:message>
        {http://xml.apache.org/axis/}exceptionName:org.alfresco.repo.webservice.repository                                                                                                         .RepositoryFault
        {http://xml.apache.org/axis/}stackTrace:
        at org.alfresco.repo.webservice.repository.RepositoryWebService.executeQuery(Repos                                                                                                         itoryWebService.java:176)
        at org.alfresco.repo.webservice.repository.RepositoryWebService.query(RepositoryWe                                                                                                         bService.java:195)
        at sun.reflect.GeneratedMethodAccessor473.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja                                                                                                         va:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCProvider.java:397)
        at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:186)
        at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:323)
        at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
        at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
        at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
        at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:454)
        at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281)
        at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327                                                                                                         )
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFil                                                                                                         terChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain                                                                                                         .java:173)
        at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:                                                                                                         96)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFil                                                                                                         terChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain                                                                                                         .java:173)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:                                                                                                         213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:                                                                                                         178)
        at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociati                                                                                                         onValve.java:175)
        at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve                                                                                                         .java:156)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:10                                                                                                         7)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConn                                                                                                         ection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:5                                                                                                         27)
        at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.                                                                                                         java:112)
        at java.lang.Thread.run(Thread.java:595)

        {http://xml.apache.org/axis/}hostname:XXX.XXX.fr


        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessor                                                                                                         Impl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructor                                                                                                         AccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
        at java.lang.Class.newInstance0(Class.java:350)
        at java.lang.Class.newInstance(Class.java:303)
        at org.apache.axis.encoding.ser.BeanDeserializer.<init>(BeanDeserializer.java:104)
        at org.apache.axis.encoding.ser.BeanDeserializer.<init>(BeanDeserializer.java:90)
        at org.alfresco.webservice.repository.RepositoryFault.getDeserializer(RepositoryFa                                                                                                         ult.java:146)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja                                                                                                         va:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.axis.encoding.ser.BaseDeserializerFactory.getSpecialized(BaseDeseria                                                                                                         lizerFactory.java:154)
        at org.apache.axis.encoding.ser.BaseDeserializerFactory.getDeserializerAs(BaseDese                                                                                                         rializerFactory.java:84)
        at org.apache.axis.encoding.DeserializationContext.getDeserializer(Deserialization                                                                                                         Context.java:464)
        at org.apache.axis.encoding.DeserializationContext.getDeserializerForType(Deserial                                                                                                         izationContext.java:547)
        at org.apache.axis.message.SOAPFaultDetailsBuilder.onStartChild(SOAPFaultDetailsBu                                                                                                         ilder.java:157)
        at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationCon                                                                                                         text.java:1035)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Abstr                                                                                                         actSAXParser.java:533)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartEleme                                                                                                         nt(XMLNSDocumentScannerImpl.java:330)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$Fragment                                                                                                         ContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1693)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocu                                                                                                         ment(XMLDocumentFragmentScannerImpl.java:368)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Config                                                                                                         uration.java:834)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Config                                                                                                         uration.java:764)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXP                                                                                                         arser.java:1242)
        at javax.xml.parsers.SAXParser.parse(SAXParser.java:375)
        at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.ja                                                                                                         va:227)
        at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
        at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
        at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecke                                                                                                         r.java:62)
        at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
        at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
        at org.apache.axis.client.Call.invoke(Call.java:2767)
        at org.apache.axis.client.Call.invoke(Call.java:2443)
        at org.apache.axis.client.Call.invoke(Call.java:2366)
        at org.apache.axis.client.Call.invoke(Call.java:1812)
        at org.alfresco.webservice.repository.RepositoryServiceSoapBindingStub.query(Repos                                                                                                         itoryServiceSoapBindingStub.java:753)
        at fr.acxio.agea.DocumentHandler.readChilds(DocumentHandler.java:456)
        at fr.acxio.agea.Connector.doExport(Connector.java:88)
        at fr.acxio.agea.Connector.main(Connector.java:72)

Quant à "RepositoryWebService.java", cette classe est dans "alfresco-remote-api.jar" qui lui-même n'est pas dans mon projet mais côté serveur.
Je l'ai décompilée et voici la source (la ligne 176 correspond à "catch(Exception ex) { }" :

public QueryResult queryParents(Reference node)
   throws RemoteException, RepositoryFault
{
   UserTransaction tx = null;
   try
   {
      tx = Utils.getUserTransaction(MessageContext.getCurrentContext());
      tx.begin();
      QuerySession querySession = new ParentsQuerySession(Utils.getBatchSize(MessageContext.getCurrentContext()), node);
      QueryResult queryResult = querySession.getNextResultsBatch(searchService, nodeService, namespaceService, dictionaryService);
      if(queryResult.getQuerySession() != null)
         querySessionCache.put(queryResult.getQuerySession(), querySession);
      tx.commit();
      return queryResult;
   }
   catch(Throwable e)
   {
      try
      {
         if(tx != null)
            tx.rollback();
      }
      catch(Exception ex) { }
      if(logger.isDebugEnabled())
         logger.error("Unexpected error occurred", e);
      throw new RepositoryFault(0, e.toString());
   }
}
Donc visiblement, le fait d'avoir augmenté le "setFetchSize" fait planter lors de l'exécution de la requête, mais je ne sais toujours ni pourquoi ni comment augmenter le nombre de résultats …
Une idée ?
laurentprad
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Voilà, j'ai fini par réussir à écrire plus de 19 000 lignes dans le csv (correspondant à 19 000 documents).
Il fallait donc le "fectchSize" mais aussi modifier dans le war alfresco les fichiers "cache-context.xml" et "ehcache-default.xml".
J'ai augmenté les paramètres (presque tous dans le doute car je remets le war d'origine arpès l'export) et cela fonctionne maintenant (par contre, même avec les paramètres augmentés mais sans le "fetchSize", il s'arrête à 1000).

Smiley Very Happy
michel
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Pour info:

Le problème lié au 1000 résultat de lucene est du au fait que lucene est configuré dans Alfresco pour s'arrêter après avoir vérifier 1000 (comme par hasard) permissions ou que la recherche ne prenne 10000 milli-secondes. Si une de ces 2 valeurs est atteinte, lucene tronque le resultSet. (ceci est visible aussi dans le navigateur de nœuds via une recherhce lucene, et noter bien que si c'est la limite de temps qui est atteinte, on peut relancer la recherche et à ce moment là, c'est la cache qui rentre en compte et on obtient plus d'éléments. Vous pouvrez faire le test en mettant une valeur plus petite et faire une recherche sur tout les documents)

Ces valeurs sont définies dans le fichier repository.properties (system.acl.maxPermissionCheckTimeMillis et system.acl.maxPermissionChecks)

Bien a vous.
wadael
Member II

Re: Web Service : requête lucene Limitée à 1000 résultats

Merci Michel pour cet éclaircissement.