mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Fix for ALF-3776: Query sorting is not support on .size and .mimetype properties of content.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@20934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -316,85 +316,112 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
|
||||
field = expandAttributeFieldName(field);
|
||||
PropertyDefinition propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1)));
|
||||
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order on content properties is not curently supported");
|
||||
}
|
||||
else if ((propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
|
||||
|| (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT)))
|
||||
{
|
||||
List<Locale> locales = searchParameters.getLocales();
|
||||
if (((locales == null) || (locales.size() == 0)))
|
||||
// Handle .size and .mimetype
|
||||
if(propertyDef == null)
|
||||
{
|
||||
if(field.endsWith(".size"))
|
||||
{
|
||||
locales = Collections.singletonList(I18NUtil.getLocale());
|
||||
}
|
||||
|
||||
if (locales.size() > 1)
|
||||
{
|
||||
throw new SearcherException("Order on text/mltext properties with more than one locale is not curently supported");
|
||||
}
|
||||
|
||||
sortLocale = locales.get(0);
|
||||
// find best field match
|
||||
|
||||
MLAnalysisMode analysisMode = getLuceneConfig().getDefaultMLSearchAnalysisMode();
|
||||
HashSet<String> allowableLocales = new HashSet<String>();
|
||||
for (Locale l : MLAnalysisMode.getLocales(analysisMode, sortLocale, false))
|
||||
{
|
||||
allowableLocales.add(l.toString());
|
||||
}
|
||||
|
||||
String sortField = field;
|
||||
|
||||
for (Object current : searcher.getReader().getFieldNames(FieldOption.INDEXED))
|
||||
{
|
||||
String currentString = (String) current;
|
||||
if (currentString.startsWith(field) && currentString.endsWith(".sort"))
|
||||
propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1, field.length()-5)));
|
||||
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
String fieldLocale = currentString.substring(field.length() + 1, currentString.length() - 5);
|
||||
if (allowableLocales.contains(fieldLocale))
|
||||
throw new SearcherException("Order for .size only supported on content properties");
|
||||
}
|
||||
}
|
||||
else if (field.endsWith(".mimetype"))
|
||||
{
|
||||
propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1, field.length()-9)));
|
||||
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order for .mimetype only supported on content properties");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order on content properties is not curently supported");
|
||||
}
|
||||
else if ((propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
|
||||
|| (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT)))
|
||||
{
|
||||
List<Locale> locales = searchParameters.getLocales();
|
||||
if (((locales == null) || (locales.size() == 0)))
|
||||
{
|
||||
locales = Collections.singletonList(I18NUtil.getLocale());
|
||||
}
|
||||
|
||||
if (locales.size() > 1)
|
||||
{
|
||||
throw new SearcherException("Order on text/mltext properties with more than one locale is not curently supported");
|
||||
}
|
||||
|
||||
sortLocale = locales.get(0);
|
||||
// find best field match
|
||||
|
||||
MLAnalysisMode analysisMode = getLuceneConfig().getDefaultMLSearchAnalysisMode();
|
||||
HashSet<String> allowableLocales = new HashSet<String>();
|
||||
for (Locale l : MLAnalysisMode.getLocales(analysisMode, sortLocale, false))
|
||||
{
|
||||
allowableLocales.add(l.toString());
|
||||
}
|
||||
|
||||
String sortField = field;
|
||||
|
||||
for (Object current : searcher.getReader().getFieldNames(FieldOption.INDEXED))
|
||||
{
|
||||
String currentString = (String) current;
|
||||
if (currentString.startsWith(field) && currentString.endsWith(".sort"))
|
||||
{
|
||||
if (fieldLocale.equals(sortLocale.toString()))
|
||||
String fieldLocale = currentString.substring(field.length() + 1, currentString.length() - 5);
|
||||
if (allowableLocales.contains(fieldLocale))
|
||||
{
|
||||
sortField = currentString;
|
||||
break;
|
||||
}
|
||||
else if (sortLocale.toString().startsWith(fieldLocale))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
if (fieldLocale.equals(sortLocale.toString()))
|
||||
{
|
||||
sortField = currentString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fieldLocale.startsWith(sortLocale.toString()))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
else if (sortLocale.toString().startsWith(fieldLocale))
|
||||
{
|
||||
sortField = currentString;
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
{
|
||||
sortField = currentString;
|
||||
}
|
||||
}
|
||||
else if (fieldLocale.startsWith(sortLocale.toString()))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
{
|
||||
sortField = currentString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field = sortField;
|
||||
field = sortField;
|
||||
|
||||
}
|
||||
else if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
else
|
||||
else if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
requiresPostSort = true;
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
else
|
||||
{
|
||||
requiresPostSort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fieldHasTerm(searcher.getReader(), field))
|
||||
{
|
||||
fields[index++] = new SortField(field, sortLocale, !sd.isAscending());
|
||||
|
@@ -1228,6 +1228,38 @@ public class ADMLuceneTest extends TestCase implements DictionaryListener
|
||||
ftsQueryWithCount(searcher, "modified:*", 2, Arrays.asList(new NodeRef[]{n14,n15}));
|
||||
ftsQueryWithCount(searcher, "modified:[MIN TO NOW]", 2, Arrays.asList(new NodeRef[]{n14,n15}));
|
||||
}
|
||||
|
||||
|
||||
private ADMLuceneSearcherImpl buildSearcher()
|
||||
{
|
||||
ADMLuceneSearcherImpl searcher = ADMLuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher);
|
||||
searcher.setNodeService(nodeService);
|
||||
searcher.setDictionaryService(dictionaryService);
|
||||
searcher.setTenantService(tenantService);
|
||||
searcher.setNamespacePrefixResolver(getNamespacePrefixResolver("namespace"));
|
||||
searcher.setQueryRegister(queryRegisterComponent);
|
||||
searcher.setQueryLanguages(((AbstractLuceneIndexerAndSearcherFactory) indexerAndSearcher).queryLanguages);
|
||||
return searcher;
|
||||
}
|
||||
|
||||
public void testFTSandSort() throws Exception
|
||||
{
|
||||
luceneFTS.pause();
|
||||
buildBaseIndex();
|
||||
ADMLuceneSearcherImpl searcher = buildSearcher();
|
||||
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
|
||||
sp.addStore(rootNodeRef.getStoreRef());
|
||||
sp.setQuery( "PATH:\"//.\"");
|
||||
sp.addQueryTemplate("ANDY", "%cm:content");
|
||||
sp.setNamespace(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
sp.excludeDataInTheCurrentTransaction(true);
|
||||
sp.addSort("@"+ContentModel.PROP_CONTENT.toString()+".size", true);
|
||||
ResultSet results = searcher.query(sp);
|
||||
assertEquals(16, results.length());
|
||||
results.close();
|
||||
}
|
||||
|
||||
public void ftsQueryWithCount(ADMLuceneSearcherImpl searcher, String query, int count)
|
||||
{
|
||||
@@ -2960,6 +2992,10 @@ public class ADMLuceneTest extends TestCase implements DictionaryListener
|
||||
}
|
||||
results.close();
|
||||
|
||||
// sort by content size
|
||||
|
||||
|
||||
|
||||
// sort by ML text
|
||||
|
||||
//Locale[] testLocales = new Locale[] { I18NUtil.getLocale(), Locale.ENGLISH, Locale.FRENCH, Locale.CHINESE };
|
||||
@@ -3030,6 +3066,58 @@ public class ADMLuceneTest extends TestCase implements DictionaryListener
|
||||
results.close();
|
||||
|
||||
luceneFTS.resume();
|
||||
|
||||
|
||||
// sort by content size
|
||||
|
||||
SearchParameters sp20 = new SearchParameters();
|
||||
sp20.addStore(rootNodeRef.getStoreRef());
|
||||
sp20.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp20.setQuery("PATH:\"//.\"");
|
||||
sp20.addSort("@" + ContentModel.PROP_CONTENT+".size", false);
|
||||
results = searcher.query(sp20);
|
||||
|
||||
Long size = null;
|
||||
for (ResultSetRow row : results)
|
||||
{
|
||||
ContentData currentBun = DefaultTypeConverter.INSTANCE.convert(ContentData.class, nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_CONTENT));
|
||||
// System.out.println(currentBun);
|
||||
if ((size != null) && (currentBun != null))
|
||||
{
|
||||
assertTrue(size.compareTo(currentBun.getSize()) >= 0);
|
||||
}
|
||||
if(currentBun != null)
|
||||
{
|
||||
size = currentBun.getSize();
|
||||
}
|
||||
}
|
||||
results.close();
|
||||
|
||||
// sort by content mimetype
|
||||
|
||||
SearchParameters sp21 = new SearchParameters();
|
||||
sp21.addStore(rootNodeRef.getStoreRef());
|
||||
sp21.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp21.setQuery("PATH:\"//.\"");
|
||||
sp21.addSort("@" + ContentModel.PROP_CONTENT+".mimetype", false);
|
||||
results = searcher.query(sp21);
|
||||
|
||||
String mimetype = null;
|
||||
for (ResultSetRow row : results)
|
||||
{
|
||||
ContentData currentBun = DefaultTypeConverter.INSTANCE.convert(ContentData.class, nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_CONTENT));
|
||||
// System.out.println(currentBun);
|
||||
if ((mimetype != null) && (currentBun != null))
|
||||
{
|
||||
assertTrue(mimetype.compareTo(currentBun.getMimetype()) >= 0);
|
||||
}
|
||||
if(currentBun != null)
|
||||
{
|
||||
mimetype = currentBun.getMimetype();
|
||||
}
|
||||
}
|
||||
results.close();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -157,79 +157,113 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
|
||||
{
|
||||
PropertyDefinition propertyDef = dictionaryService.getProperty(QName.createQName(field.substring(1)));
|
||||
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order on content properties is not curently supported");
|
||||
}
|
||||
else if ((propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)) || (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT)))
|
||||
{
|
||||
List<Locale> locales = lqp.getSearchParameters().getLocales();
|
||||
if (((locales == null) || (locales.size() == 0)))
|
||||
// Handle .size and .mimetype
|
||||
if(propertyDef == null)
|
||||
{
|
||||
if(field.endsWith(".size"))
|
||||
{
|
||||
locales = Collections.singletonList(I18NUtil.getLocale());
|
||||
}
|
||||
|
||||
if (locales.size() > 1)
|
||||
{
|
||||
throw new SearcherException("Order on text/mltext properties with more than one locale is not curently supported");
|
||||
}
|
||||
|
||||
sortLocale = locales.get(0);
|
||||
// find best field match
|
||||
|
||||
HashSet<String> allowableLocales = new HashSet<String>();
|
||||
MLAnalysisMode analysisMode = lqp.getConfig().getDefaultMLSearchAnalysisMode();
|
||||
for (Locale l : MLAnalysisMode.getLocales(analysisMode, sortLocale, false))
|
||||
{
|
||||
allowableLocales.add(l.toString());
|
||||
}
|
||||
|
||||
String sortField = field;
|
||||
|
||||
for (Object current : lqp.getIndexReader().getFieldNames(FieldOption.INDEXED))
|
||||
{
|
||||
String currentString = (String) current;
|
||||
if (currentString.startsWith(field) && currentString.endsWith(".sort"))
|
||||
propertyDef = dictionaryService.getProperty(QName.createQName(field.substring(1, field.length()-5)));
|
||||
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
String fieldLocale = currentString.substring(field.length() + 1, currentString.length() - 5);
|
||||
if (allowableLocales.contains(fieldLocale))
|
||||
throw new SearcherException("Order for .size only supported on content properties");
|
||||
}
|
||||
else
|
||||
{
|
||||
return field;
|
||||
}
|
||||
}
|
||||
else if (field.endsWith(".mimetype"))
|
||||
{
|
||||
propertyDef = dictionaryService.getProperty(QName.createQName(field.substring(1, field.length()-9)));
|
||||
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order for .mimetype only supported on content properties");
|
||||
}
|
||||
else
|
||||
{
|
||||
return field;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return field;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
throw new SearcherException("Order on content properties is not curently supported");
|
||||
}
|
||||
else if ((propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)) || (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT)))
|
||||
{
|
||||
List<Locale> locales = lqp.getSearchParameters().getLocales();
|
||||
if (((locales == null) || (locales.size() == 0)))
|
||||
{
|
||||
locales = Collections.singletonList(I18NUtil.getLocale());
|
||||
}
|
||||
|
||||
if (locales.size() > 1)
|
||||
{
|
||||
throw new SearcherException("Order on text/mltext properties with more than one locale is not curently supported");
|
||||
}
|
||||
|
||||
sortLocale = locales.get(0);
|
||||
// find best field match
|
||||
|
||||
HashSet<String> allowableLocales = new HashSet<String>();
|
||||
MLAnalysisMode analysisMode = lqp.getConfig().getDefaultMLSearchAnalysisMode();
|
||||
for (Locale l : MLAnalysisMode.getLocales(analysisMode, sortLocale, false))
|
||||
{
|
||||
allowableLocales.add(l.toString());
|
||||
}
|
||||
|
||||
String sortField = field;
|
||||
|
||||
for (Object current : lqp.getIndexReader().getFieldNames(FieldOption.INDEXED))
|
||||
{
|
||||
String currentString = (String) current;
|
||||
if (currentString.startsWith(field) && currentString.endsWith(".sort"))
|
||||
{
|
||||
if (fieldLocale.equals(sortLocale.toString()))
|
||||
String fieldLocale = currentString.substring(field.length() + 1, currentString.length() - 5);
|
||||
if (allowableLocales.contains(fieldLocale))
|
||||
{
|
||||
sortField = currentString;
|
||||
break;
|
||||
}
|
||||
else if (sortLocale.toString().startsWith(fieldLocale))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
if (fieldLocale.equals(sortLocale.toString()))
|
||||
{
|
||||
sortField = currentString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fieldLocale.startsWith(sortLocale.toString()))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
else if (sortLocale.toString().startsWith(fieldLocale))
|
||||
{
|
||||
sortField = currentString;
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
{
|
||||
sortField = currentString;
|
||||
}
|
||||
}
|
||||
else if (fieldLocale.startsWith(sortLocale.toString()))
|
||||
{
|
||||
if (sortField.equals(field) || (currentString.length() < sortField.length()))
|
||||
{
|
||||
sortField = currentString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field = sortField;
|
||||
|
||||
}
|
||||
|
||||
field = sortField;
|
||||
|
||||
}
|
||||
else if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
else if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME))
|
||||
{
|
||||
field = field + ".sort";
|
||||
DataTypeDefinition dataType = propertyDef.getDataType();
|
||||
String analyserClassName = dataType.getAnalyserClassName();
|
||||
if (analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()))
|
||||
{
|
||||
field = field + ".sort";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
Reference in New Issue
Block a user