1
votes

I got an error within Alfresco search page, when I try to sort by my custom property:

environment:

  1. Alfresco 5.0.1
  2. Postgres
  3. Solr4
  4. tomcat 7

Error:

2015-05-12 12:54:34,864  ERROR [solr.core.SolrCore] [http-bio-8443-exec-7] org.apache.solr.common.SolrException: sort param could not be parsed as a query, and is not a field that exists in the index: @{http://global.oup.com/dam/model/1.0}supplierName
        at org.apache.solr.search.QueryParsing.parseSortSpec(QueryParsing.java:358)
        at org.alfresco.solr.query.AbstractQParser.getSort(AbstractQParser.java:569)
        at org.apache.solr.handler.component.QueryComponent.prepare(QueryComponent.java:175)
        at org.apache.solr.handler.component.AlfrescoSearchHandler.handleRequestBody(AlfrescoSearchHandler.java:233)
        at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)
        at org.apache.solr.core.SolrCore.execute(SolrCore.java:1962)
        at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:777)
        at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:418)
        at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:207)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:613)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.solr.search.SyntaxError: Expected identifier at pos 0 str='@{http://global.oup.com/dam/model/1.0}supplierName desc'
        at org.apache.solr.search.QueryParsing$StrParser.getId(QueryParsing.java:770)
        at org.apache.solr.search.QueryParsing$StrParser.getId(QueryParsing.java:749)
        at org.apache.solr.search.FunctionQParser.parseValueSource(FunctionQParser.java:345)
        at org.apache.solr.search.FunctionQParser.parse(FunctionQParser.java:68)
        at org.apache.solr.search.QParser.getQuery(QParser.java:141)
        at org.apache.solr.search.QueryParsing.parseSortSpec(QueryParsing.java:286)
        ... 25 more

My custom field is configured as following into the content model file:

<types>
     <type name="oup:asset">
         <title>Asset</title>
         <parent>ipp:asset</parent>

         <property name='oup:supplierName'>
              <title>Supplier Name</title>
               <description>Name of the supplier (note there is also a supplier
                        specified on asset rights)
               </description>
               <type>d:mltext</type>
               <mandatory enforced='false'>true</mandatory>
               <multiple>true</multiple>
               <index enabled="true">
                   <atomic>true</atomic>
                   <stored>false</stored>
                   <tokenised>both</tokenised>
               </index>
         </property>
     </type>
</types>

As far as I know, the index configuration should be fine, I tried also putting atomic to false with no luck.

The above configuration was working fine using Alfresco 4.1.1 and Solr 1, but now, the porting to Alfresco 5 and Solr 4 does not work.

I tried the js code from the javascript console in the Alfresco Admin page using the search service and the sorting works fine for cm:name but not for oup:supplierName, following the code:

var orderedNodes = search.luceneSearch("@cm\\:name:\"my-file\"", "@oup:supplierName", false);
logger.log("retrieved " + orderedNodes.length + " nodes\n");

Any Idea ?

3
have tried my solution? - Krutik Jayswal
I tried your solution, but is not that the problem. The main problem is the <multiple>true</multiple>. Also, I read this article: docs.alfresco.com/5.0/concepts/search-fts-config.html, it seems that for Alfresco 5 there is another tag for the faceted search which I need to implement, but it seems not working with <atomic>true</atomic> - Giuseppe Adaldo

3 Answers

1
votes

I found the problem, it's a Solr4 bug/behavior, when it tries to perform the sorting of multiple properties like the Alfresco multivalued properties -

I found this piece of code in the Solr web app:

private void addSortSearchFields( PropertyDefinition propertyDefinition , IndexedField indexedField)
{
    // Can only order on single valued fields
    DataTypeDefinition dataTypeDefinition = propertyDefinition.getDataType();
    if(dataTypeDefinition.getName().equals(DataTypeDefinition.TEXT))
    { 
        if(propertyDefinition.isMultiValued() == false)
        {
            if ((propertyDefinition.getIndexTokenisationMode() == IndexTokenisationMode.FALSE)
                    || (propertyDefinition.getIndexTokenisationMode() == IndexTokenisationMode.BOTH))
            {
                indexedField.addField(getFieldForText(false, false, true, propertyDefinition), false, true);
            }
            else if (isIdentifierTextProperty(propertyDefinition.getName()))
            {
                indexedField.addField(getFieldForText(false, false, false, propertyDefinition), false, false);   
            }
            else
            {
                indexedField.addField(getFieldForText(false, true, false, propertyDefinition), false, false);
            }
        }
    }

    if(dataTypeDefinition.getName().equals(DataTypeDefinition.MLTEXT))
    {
        if(propertyDefinition.isMultiValued() == false)
        {
            if ((propertyDefinition.getIndexTokenisationMode() == IndexTokenisationMode.FALSE)
                    || (propertyDefinition.getIndexTokenisationMode() == IndexTokenisationMode.BOTH))
            {
                indexedField.addField(getFieldForText(false, false, true, propertyDefinition), false, true);
            }
            else
            {
                indexedField.addField(getFieldForText(false, true, false, propertyDefinition), false, false);
            }
        }
    }
}

So, it does the sorting only if propertyDefinition.isMultiValued() == false and then it throws the exception later in the code because it is not able to map the QName.

Is that right?

Is there a way to skip it without coding?

If not, I think the only way to fix it is to override the Spring bean in some way to use our custom function, any suggestion to do so without doing the deploy of Solr too?

Or possibly a Spring AOP, but to be honest I don't like this idea.

Any possible solution?

1
votes

I found a work-around:

  • create a new property in the content model, just text. This one is a string representation of the multivalued field, indexed as well;

  • create a behavior with the two policies: onUpdatePolicy and onCreatePolicy that makes the string representation of the multivalued field;

  • create a patch (Spring bean) that set up the value for the new field for all the old content;

The field is hidden for all the UI and is not possible to be set up by a user. It is indexed to get the faceted search working in alfresco 5 and sorting as well.

The described solution is the best I found, hope it helps. Any suggestion is welcome.

0
votes

Change d:mltext to d:text only.If you don't require multilingual support.Some time d:mltext creates problem.

May be below will help you.

Atomic="true"
If this is true, the property is indexed in the transaction if not the property is indexed in the background. Indexing of content that requires transformation before being indexed (e.g. PDFs) will only obey Atomic=true if the transformation takes less time than the value specified for lucene.maxAtomicTransformationTime.

lucene.maxAtomicTransformationTime=20 Transformations of content that are likely to take longer than this time (in millis) will be done in the background. To force atomic content indexing, increase this value.

You must know that

SOLR does not perform in-transaction indexing.