cancel
Showing results for 
Search instead for 
Did you mean: 

alfresco5.0 xpath sorting problem

dicolar
Champ in-the-making
Champ in-the-making
hi there,
recently i'm programming with the newest Alfresco5.0.0d community-edition.
since considering of improving the performance of indexing,alfresco will index by a period of 15 secs.
but here comes the problem,after i uploaded/created a document & i search it immediately by Lucene(it calls the Solr in fact),it returns the resultset which does not contain the newest object i created.
so,i have to give up my idea of searching by Lucene and go to trying  XPATH.
but now again the problem comes,where is the JCR-XPATH??
this is my query string:

/app:company_home//*[subtypeOf('cm:content')] order by @cm:name

when i concat a string of 'order by @cm:name', it throws a sweet exception to me saying it cannot recognize the orderby… segment.
and i didn't see the JCR-XPATH field in SearchService anymore.i also searched in the source code with keyword of 'jcr',but no useful result came out.

so how can i sort the resultset of xpath-searching? or do u have any idea of IMMEDIATE-SEARCHING?
2 REPLIES 2

afaust
Legendary Innovator
Legendary Innovator
Hello,

you can use <a href="http://docs.alfresco.com/4.2/concepts/intrans-metadata.html">Transactional Metadata Queries</a> to search for content without waiting for the indexing process. This feature does not support PATH though, but judging from your query you don't need a PATH, since you basically search for all content in the system.
Also, you can still use SearchService.selectNodes to perform transactional XPath queries.

Regards
Axel

dicolar
Champ in-the-making
Champ in-the-making
thank u 4 answering my question!
the xpath query string i attached was just an example in fact.and i do need the PATH feature indeed.
besides, i compared the 2 java source files of 5.0.x&4.2.x,found something intresting.
see here: 5.0.d NodeSearcher.java


public List<NodeRef> selectNodes(NodeRef contextNodeRef, String xpathIn,
            QueryParameterDefinition[] paramDefs, NamespacePrefixResolver namespacePrefixResolver,
            boolean followAllParentLinks, String <strong>language</strong>) {
        try
        {
            String xpath = xpathIn;

            <strong>List<AttributeOrder> order = null;</strong>

            DocumentNavigator documentNavigator = new DocumentNavigator(dictionaryService, nodeService, searchService,
                    namespacePrefixResolver, followAllParentLinks);
            NodeServiceXPath nsXPath = new NodeServiceXPath(xpath, documentNavigator, paramDefs);
            for (String prefix : namespacePrefixResolver.getPrefixes())
            {
                nsXPath.addNamespace(prefix, namespacePrefixResolver.getNamespaceURI(prefix));
            }
            @SuppressWarnings("rawtypes")
            List list = nsXPath.selectNodes(nodeService.getPrimaryParent(contextNodeRef));
            HashSet<NodeRef> unique = new HashSet<NodeRef>(list.size());
            for (Object o : list)
            {
                if (o instanceof ChildAssociationRef)
                {
                    unique.add(((ChildAssociationRef) o).getChildRef());
                }
                else if (o instanceof DocumentNavigator.Property)
                {
                    unique.add(((DocumentNavigator.Property) o).parent);
                }
                else
                {
                    throw new XPathException("Xpath expression must only select nodes");
                }
            }

            List<NodeRef> answer = new ArrayList<NodeRef>(unique.size());
            answer.addAll(unique);
            if (order != null)…

yes,alfresco team had never used the parameter <strong>language</strong>,and the list of <strong>order</strong> is forever a null value.
but in the 4.2.d version's code,it checks the parameter of <strong>language</strong>,if it equals to 'jcr-xpath',the programme will analize the order… segment and perform an in-memory sorting.
here is the missing code:

List<AttributeOrder> order = null;
         // replace element
         order = new ArrayList<AttributeOrder>();
         // We do not allow variable substitution with this pattern
         xpath = xpath.replaceAll("element\\(\\s*(\\*|\\w*:\\w*)\\s*,\\s*(\\*|\\w*:\\w*)\\s*\\)", "$1[subtypeOf(\"$2\")]");
         String split[] = xpath.split("order\\s*by\\s*", 2);
         xpath = split[0];

         if (split.length > 1 && split[1].length() > 0) {
            String clauses[] = split[1].split("\\s,\\s");

            for (String clause : clauses) {
               if (clause.startsWith("@")) {
                  String attribute = clause.replaceFirst("@(\\p{Alpha}[\\w:]*)(?:\\s+(.*))?", "$1");
                  String sort = clause.replaceFirst("@(\\p{Alpha}[\\w:]*)(?:\\s+(.*))?", "$2");

                  if (sort.length() == 0) {
                     sort = "ascending";
                  }

                  QName attributeQName = QName.createQName(attribute, namespacePrefixResolver);

                  order.add(new AttributeOrder(attributeQName, sort.equalsIgnoreCase("ascending")));
               } else if (clause.startsWith("jcr:score")) {
                  // ignore jcr:score ordering
               } else {
                  throw new IllegalArgumentException("Malformed order by expression " + split[1]);
               }
            }
         }

i put it in the NodeSearcher.java,then built it,and now SORTING available!!although it's just a little…slow Smiley Happy
but it doesnot matter,because xpath query is just used 4 a narrow scope searching,like retrieving the children of a parent folder.

and now i just doubt that y does alfresco team remove the missing code…