mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-23 18:05:32 +00:00
SLNG-8110: Add post query sort for datetime it required (default field in the index only sorts to date)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9971 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
cef534a8c1
commit
ec903f2dc1
@ -29,6 +29,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
@ -77,6 +78,16 @@ public abstract class AbstractResultSetRow implements ResultSetRow
|
||||
return getResultSet().getNodeRef(getIndex());
|
||||
}
|
||||
|
||||
public QName getQName()
|
||||
{
|
||||
return getResultSet().getChildAssocRef(getIndex()).getQName();
|
||||
}
|
||||
|
||||
public ChildAssociationRef getChildAssocRef()
|
||||
{
|
||||
return getResultSet().getChildAssocRef(getIndex());
|
||||
}
|
||||
|
||||
public float getScore()
|
||||
{
|
||||
return getResultSet().getScore(getIndex());
|
||||
@ -92,6 +103,11 @@ public abstract class AbstractResultSetRow implements ResultSetRow
|
||||
return Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
||||
public Serializable getValue(Path path)
|
||||
{
|
||||
return properties.get(path);
|
||||
}
|
||||
|
||||
protected Map<QName, Serializable> getDirectProperties()
|
||||
{
|
||||
return Collections.<QName, Serializable>emptyMap();
|
||||
|
@ -44,6 +44,7 @@ import org.alfresco.repo.search.impl.NodeSearcher;
|
||||
import org.alfresco.repo.search.impl.lucene.QueryParser.Operator;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser;
|
||||
import org.alfresco.repo.search.results.SortedResultSet;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
@ -261,6 +262,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
|
||||
Hits hits;
|
||||
|
||||
boolean requiresPostSort = false;
|
||||
if (searchParameters.getSortDefinitions().size() > 0)
|
||||
{
|
||||
int index = 0;
|
||||
@ -284,6 +286,10 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
else
|
||||
{
|
||||
requiresPostSort = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -306,6 +312,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
|
||||
}
|
||||
hits = searcher.search(query, new Sort(fields));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -313,7 +320,16 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
}
|
||||
|
||||
Path[] paths = searchParameters.getAttributePaths().toArray(new Path[0]);
|
||||
return new LuceneResultSet(hits, searcher, nodeService, tenantService, paths, searchParameters);
|
||||
ResultSet rs = new LuceneResultSet(hits, searcher, nodeService, tenantService, paths, searchParameters);
|
||||
if(requiresPostSort)
|
||||
{
|
||||
ResultSet sorted = new SortedResultSet(rs, nodeService, searchParameters, namespacePrefixResolver);
|
||||
return sorted;
|
||||
}
|
||||
else
|
||||
{
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
|
@ -409,8 +409,12 @@ public class ADMLuceneTest extends TestCase
|
||||
nodeService.addChild(n12, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common"));
|
||||
nodeService.addChild(n13, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common"));
|
||||
|
||||
documentOrder = new NodeRef[] { rootNodeRef, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14 };
|
||||
documentOrder = new NodeRef[] { rootNodeRef, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n3, n1, n2 };
|
||||
|
||||
nodeService.addAspect(n3, ContentModel.ASPECT_AUDITABLE, null);
|
||||
nodeService.addAspect(n1, ContentModel.ASPECT_AUDITABLE, null);
|
||||
nodeService.setProperty(n1, ContentModel.PROP_MODIFIED, new Date(new Date().getTime() - 1000*60*60));
|
||||
nodeService.addAspect(n2, ContentModel.ASPECT_AUDITABLE, null);
|
||||
}
|
||||
|
||||
private double orderDoubleCount = -0.11d;
|
||||
@ -1617,7 +1621,7 @@ public class ADMLuceneTest extends TestCase
|
||||
date = currentBun;
|
||||
}
|
||||
results.close();
|
||||
|
||||
|
||||
SearchParameters sp_7 = new SearchParameters();
|
||||
sp_7.addStore(rootNodeRef.getStoreRef());
|
||||
sp_7.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
@ -1629,7 +1633,7 @@ public class ADMLuceneTest extends TestCase
|
||||
for (ResultSetRow row : results)
|
||||
{
|
||||
Date currentBun = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_MODIFIED));
|
||||
// System.out.println(currentBun);
|
||||
//System.out.println("A " + currentBun + " "+row.getQName());
|
||||
if (date != null)
|
||||
{
|
||||
assertTrue(date.compareTo(currentBun) <= 0);
|
||||
@ -1835,7 +1839,7 @@ public class ADMLuceneTest extends TestCase
|
||||
sp17.addSort("cabbage", false);
|
||||
results = searcher.query(sp17);
|
||||
results.close();
|
||||
|
||||
|
||||
luceneFTS.resume();
|
||||
}
|
||||
|
||||
@ -2155,6 +2159,9 @@ public class ADMLuceneTest extends TestCase
|
||||
indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n5, QName.createQName("{namespace}twelve"), n12));
|
||||
indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n12, QName.createQName("{namespace}thirteen"), n13));
|
||||
indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n13, QName.createQName("{namespace}fourteen"), n14));
|
||||
indexer.updateNode(n3);
|
||||
indexer.updateNode(n1);
|
||||
indexer.updateNode(n2);
|
||||
indexer.prepare();
|
||||
indexer.commit();
|
||||
}
|
||||
|
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.search.results;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.search.SearcherException;
|
||||
import org.alfresco.repo.search.impl.lucene.LuceneResultSetRow;
|
||||
import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetMetaData;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.lucene.search.SortField;
|
||||
|
||||
public class SortedResultSet implements ResultSet
|
||||
{
|
||||
ArrayList<NodeRefAndScore> nodeRefsAndScores;
|
||||
|
||||
NodeService nodeService;
|
||||
|
||||
SearchParameters searchParameters;
|
||||
|
||||
ResultSet resultSet;
|
||||
|
||||
public SortedResultSet(ResultSet resultSet, NodeService nodeService, SearchParameters searchParameters, NamespacePrefixResolver namespacePrefixResolver)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
this.searchParameters = searchParameters;
|
||||
this.resultSet = resultSet;
|
||||
|
||||
nodeRefsAndScores = new ArrayList<NodeRefAndScore>(resultSet.length());
|
||||
for (ResultSetRow row : resultSet)
|
||||
{
|
||||
nodeRefsAndScores.add(new NodeRefAndScore(row.getNodeRef(), row.getScore()));
|
||||
}
|
||||
ArrayList<AttributeOrder> order = new ArrayList<AttributeOrder>();
|
||||
for (SortDefinition sd : searchParameters.getSortDefinitions())
|
||||
{
|
||||
switch (sd.getSortType())
|
||||
{
|
||||
case FIELD:
|
||||
String field = sd.getField();
|
||||
if (field.startsWith("@"))
|
||||
{
|
||||
QName qname = expandAttributeFieldName(field, namespacePrefixResolver);
|
||||
order.add(new AttributeOrder(qname, sd.isAscending()));
|
||||
}
|
||||
break;
|
||||
case DOCUMENT:
|
||||
// ignore
|
||||
break;
|
||||
case SCORE:
|
||||
// ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
orderNodes(nodeRefsAndScores, order);
|
||||
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
resultSet.close();
|
||||
}
|
||||
|
||||
public ChildAssociationRef getChildAssocRef(int n)
|
||||
{
|
||||
return nodeService.getPrimaryParent(nodeRefsAndScores.get(n).nodeRef);
|
||||
}
|
||||
|
||||
public List<NodeRef> getNodeRefs()
|
||||
{
|
||||
ArrayList<NodeRef> nodeRefs = new ArrayList<NodeRef>(length());
|
||||
for (ResultSetRow row : this)
|
||||
{
|
||||
nodeRefs.add(row.getNodeRef());
|
||||
}
|
||||
return nodeRefs;
|
||||
}
|
||||
|
||||
public List<ChildAssociationRef> getChildAssocRefs()
|
||||
{
|
||||
ArrayList<ChildAssociationRef> cars = new ArrayList<ChildAssociationRef>(length());
|
||||
for (ResultSetRow row : this)
|
||||
{
|
||||
cars.add(row.getChildAssocRef());
|
||||
}
|
||||
return cars;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef(int n)
|
||||
{
|
||||
return nodeRefsAndScores.get(n).nodeRef;
|
||||
}
|
||||
|
||||
public Path[] getPropertyPaths()
|
||||
{
|
||||
return resultSet.getPropertyPaths();
|
||||
}
|
||||
|
||||
public ResultSetMetaData getResultSetMetaData()
|
||||
{
|
||||
return resultSet.getResultSetMetaData();
|
||||
}
|
||||
|
||||
public ResultSetRow getRow(int i)
|
||||
{
|
||||
if (i < length())
|
||||
{
|
||||
return new SortedResultSetRow(this, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SearcherException("Invalid row");
|
||||
}
|
||||
}
|
||||
|
||||
public float getScore(int n)
|
||||
{
|
||||
return nodeRefsAndScores.get(n).score;
|
||||
}
|
||||
|
||||
public int length()
|
||||
{
|
||||
return nodeRefsAndScores.size();
|
||||
}
|
||||
|
||||
public Iterator<ResultSetRow> iterator()
|
||||
{
|
||||
return new SortedResultSetRowIterator(this);
|
||||
}
|
||||
|
||||
private void orderNodes(List<NodeRefAndScore> answer, List<AttributeOrder> order)
|
||||
{
|
||||
Collections.sort(answer, new NodeRefAndScoreComparator(nodeService, order));
|
||||
}
|
||||
|
||||
private QName expandAttributeFieldName(String field, NamespacePrefixResolver namespacePrefixResolver)
|
||||
{
|
||||
QName qname;
|
||||
// Check for any prefixes and expand to the full uri
|
||||
if (field.charAt(1) != '{')
|
||||
{
|
||||
int colonPosition = field.indexOf(':');
|
||||
if (colonPosition == -1)
|
||||
{
|
||||
// use the default namespace
|
||||
qname = QName.createQName(NamespaceService.DEFAULT_URI, field.substring(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the prefix
|
||||
qname = QName.createQName(field.substring(1, colonPosition), field.substring(colonPosition + 1), namespacePrefixResolver);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qname = QName.createQName(field.substring(1));
|
||||
}
|
||||
return qname;
|
||||
}
|
||||
|
||||
static class NodeRefAndScoreComparator implements Comparator<NodeRefAndScore>
|
||||
{
|
||||
List<AttributeOrder> order;
|
||||
|
||||
NodeService nodeService;
|
||||
|
||||
NodeRefAndScoreComparator(NodeService nodeService, List<AttributeOrder> order)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(NodeRefAndScore n1, NodeRefAndScore n2)
|
||||
{
|
||||
for (AttributeOrder attributeOrder : order)
|
||||
{
|
||||
Serializable o1 = nodeService.getProperty(n1.nodeRef, attributeOrder.attribute);
|
||||
Serializable o2 = nodeService.getProperty(n2.nodeRef, attributeOrder.attribute);
|
||||
|
||||
if (o1 == null)
|
||||
{
|
||||
if (o2 == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return attributeOrder.ascending ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (o2 == null)
|
||||
{
|
||||
return attributeOrder.ascending ? 1 : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((o1 instanceof Comparable) && (o2 instanceof Comparable))
|
||||
{
|
||||
return (attributeOrder.ascending ? 1 : -1) * ((Comparable) o1).compareTo((Comparable) o2);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AttributeOrder
|
||||
{
|
||||
QName attribute;
|
||||
|
||||
boolean ascending;
|
||||
|
||||
AttributeOrder(QName attribute, boolean ascending)
|
||||
{
|
||||
this.attribute = attribute;
|
||||
this.ascending = ascending;
|
||||
}
|
||||
}
|
||||
|
||||
private static class NodeRefAndScore
|
||||
{
|
||||
NodeRef nodeRef;
|
||||
|
||||
float score;
|
||||
|
||||
NodeRefAndScore(NodeRef nodeRef, float score)
|
||||
{
|
||||
this.nodeRef = nodeRef;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.search.results;
|
||||
|
||||
import org.alfresco.repo.search.AbstractResultSetRow;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
|
||||
/**
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class SortedResultSetRow extends AbstractResultSetRow implements ResultSetRow
|
||||
{
|
||||
|
||||
/**
|
||||
* @param resultSet
|
||||
* @param index
|
||||
*/
|
||||
public SortedResultSetRow(SortedResultSet resultSet, int index)
|
||||
{
|
||||
super(resultSet, index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.search.results;
|
||||
|
||||
import org.alfresco.repo.search.AbstractResultSetRowIterator;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
|
||||
/**
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class SortedResultSetRowIterator extends AbstractResultSetRowIterator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param resultSet
|
||||
*/
|
||||
public SortedResultSetRowIterator(ResultSet resultSet)
|
||||
{
|
||||
super(resultSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetRow next()
|
||||
{
|
||||
return new SortedResultSetRow((SortedResultSet)getResultSet(), moveToNextPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetRow previous()
|
||||
{
|
||||
return new SortedResultSetRow((SortedResultSet)getResultSet(), moveToPreviousPosition());
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user