cancel
Showing results for 
Search instead for 
Did you mean: 

Pager with Lucene Search

emmy
Champ in-the-making
Champ in-the-making
Hi,
I have created a webscript that search all the nodes having specified some parameters (i.e name, update date, created date…).
I have used the function childrenByLuceneSearch in the template, but if the results are 1500 for example the wait time is too long.
Is possible to limit those results for example from 10 to 20, from 20 to 30 …. like a pager?
I would like also to know the total number of results query.

Thanks in advance,
Emanuela
8 REPLIES 8

kevinr
Star Contributor
Star Contributor
The repository Lucene search does not yet supported paged result sets. You will have to implement the paging yourself in the client. We perform a similar pattern with our OpenSearch webscripts. The search is performed in the repo, but only the requested page of the results are returned in XML to the template.

You can use the ?size operator in freemarker to find the size of a sequence (list) from the results of the childrenByLuceneSearch operation.

Thanks,

Kevin

witho
Champ on-the-rise
Champ on-the-rise
I have the same problem with a doclit portlet I have created to find the last 20 documents uploaded to the repoitory. The thing is that I have to search every docs in the repository order by date and only print the first 20 documents and the others just set at display:none.

Is there any better solution in order to minimize the waiting time?

Thanks a lot!!!

kevinr
Star Contributor
Star Contributor
Set the maximum results to return to 20 items directly on the API call, then sort by date using the sorting options on the API call i.e. don't do the cropping/sorting post process it in javascript/freemarker.

http://wiki.alfresco.com/wiki/3.2_JavaScript_API#Search_API

Kev

witho
Champ on-the-rise
Champ on-the-rise
The problem is that I can't find where are the code of the search calls. These are the calls in the javascript/freemarker:

<#if args.h?exists>
   <#assign docs=companyhome.nodeByReference[args.h].children?sort_by(["properties","cm:created"])?reverse>
<#else>
   <#assign docs=companyhome.childrenByLuceneSearch[args.q]?sort_by(["properties","cm:created"])?reverse>
</#if>

Do you know where are the source of these calls where I could change the code to return only 20 items sorts by date?

Thanks!!!

kevinr
Star Contributor
Star Contributor
org.alfresco.repo.template.TemplateNode and it's associated base classes.

witho
Champ on-the-rise
Champ on-the-rise
Sorry kevinr, but I could not get with the code where I have to set the resuts return size to 20. I am looking into TemplateNode and its base classes but I can't get it.

Do you know where can I set these parameters?

Thank you.

kevinr
Star Contributor
Star Contributor
You would need to modify or extend the getChildrenByLuceneSearch() method.

To be honest, if possible you are much better using a WebScript for this - as then you have full access to the greatly improved JavaScript Search API which includes parameters for setting max results returned, multi-field sorting etc.etc. Obviously this is not possible if you have to perform the logic directly in the template…

Kev

witho
Champ on-the-rise
Champ on-the-rise
Hi,

Finally I got a valid solution for me. I replicate the method getChildrenByLuceneSearch the class LuceneSearchResultsMap and also the method get inside this class. I make a new lucene search that sort the documents by created date and get only the 20 first. This is my method get:


    public Object get(Object key)
    {
        // execute the search
        String search = key.toString();
       List<TemplateNode> nodes = null;
        HashSet<NodeRef> nodeRefs = new HashSet<NodeRef>();

        // check if a full Lucene search string has been supplied or extracted from XML
        if (search != null && search.length() != 0)
        {
            // perform the search against the repo
            ResultSet results = null;
            try
            {
                SearchParameters sp = new SearchParameters();
                sp.addStore(this.parent.getNodeRef().getStoreRef());
                sp.setLanguage(SearchService.LANGUAGE_LUCENE);
                sp.setQuery(search);
                sp.addSort("CREATED", false);
                sp.setLimitBy(LimitBy.FINAL_SIZE);
                int limit = 20;
                sp.setLimit(limit);

                results = this.services.getSearchService().query(sp);

                if (results.length() != 0)
                {
                    nodes = new ArrayList<TemplateNode>(results.length());
                    for (ResultSetRow row : results)
                    {
                        NodeRef nodeRef = row.getNodeRef();
                        if (!nodeRefs.contains(nodeRef))
                        {
                            nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver()));
                            nodeRefs.add(nodeRef);
                        }
                    }
                }
            }
            catch (Throwable err)
            {
                throw new AlfrescoRuntimeException("Failed to execute search: " + search, err);
            }
            finally
            {
                if (results != null)
                {
                    results.close();
                }
            }
        }

        return nodes != null ? nodes : (List) Collections.emptyList();
    }

Thanks for your help and I hope this may help somebody too.