RM: Lenient date format for lucene queries against datetime

- supports:
    "yyyy-MM-dd'T'HH:mm:ss.SSS", 
    "yyyy-MM-dd", 
    "yyyy-MM-dd'T'HH:mm:ss.SSSZ", 
    "yyyy-MM-dd'T'HH:mm:ss", 
    "yyyy-MM-dd'T'HH:mm", 
    "yyyy-MM-dd'T'HH", 
    "yyyy-MM-dd'T'",
    "yyyy-MMM-dd'T'HH:mm:ss.SSS", 
    "yyyy-MMM-dd", 
    "yyyy-MMM-dd'T'HH:mm:ss.SSSZ", 
    "yyyy-MMM-dd'T'HH:mm:ss", 
    "yyyy-MMM-dd'T'HH:mm", 
    "yyyy-MMM-dd'T'HH", 
    "yyyy-MMM-dd'T'"

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16738 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2009-10-07 19:39:07 +00:00
parent 0b12552799
commit d014d715d3
3 changed files with 132 additions and 133 deletions

View File

@@ -652,6 +652,7 @@ public class ADMLuceneTest extends TestCase
} }
} }
public void testQuoting() throws Exception public void testQuoting() throws Exception
{ {
testTX.commit(); testTX.commit();
@@ -664,12 +665,10 @@ public class ADMLuceneTest extends TestCase
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
sp.excludeDataInTheCurrentTransaction(true); sp.excludeDataInTheCurrentTransaction(true);
ResultSet results = serviceRegistry.getSearchService().query(sp); ResultSet results = serviceRegistry.getSearchService().query(sp);
results.close(); results.close();
} }
public void testPublicServiceSearchServicePaging() throws Exception public void testPublicServiceSearchServicePaging() throws Exception
{ {
testTX.commit(); testTX.commit();
@@ -718,7 +717,7 @@ public class ADMLuceneTest extends TestCase
results = serviceRegistry.getSearchService().query(sp); results = serviceRegistry.getSearchService().query(sp);
assertEquals(2, results.length()); assertEquals(2, results.length());
results.close(); results.close();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.setMaxPermissionChecks(2); sp.setMaxPermissionChecks(2);
results = serviceRegistry.getSearchService().query(sp); results = serviceRegistry.getSearchService().query(sp);
@@ -873,7 +872,7 @@ public class ADMLuceneTest extends TestCase
searcher.setNamespacePrefixResolver(getNamespacePrefixResolver("namespace")); searcher.setNamespacePrefixResolver(getNamespacePrefixResolver("namespace"));
searcher.setQueryRegister(queryRegisterComponent); searcher.setQueryRegister(queryRegisterComponent);
searcher.setQueryLanguages(((AbstractLuceneIndexerAndSearcherFactory) indexerAndSearcher).queryLanguages); searcher.setQueryLanguages(((AbstractLuceneIndexerAndSearcherFactory) indexerAndSearcher).queryLanguages);
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
@@ -884,7 +883,7 @@ public class ADMLuceneTest extends TestCase
sp.addSort(ContentModel.PROP_NODE_UUID.toString(), true); sp.addSort(ContentModel.PROP_NODE_UUID.toString(), true);
ResultSet results = searcher.query(sp); ResultSet results = searcher.query(sp);
assertEquals(15, results.length()); assertEquals(15, results.length());
String f = null; String f = null;
for (ResultSetRow row : results) for (ResultSetRow row : results)
{ {
@@ -896,11 +895,9 @@ public class ADMLuceneTest extends TestCase
} }
f = currentBun; f = currentBun;
} }
results.close(); results.close();
sp = new SearchParameters(); sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
@@ -911,7 +908,7 @@ public class ADMLuceneTest extends TestCase
sp.addSort(ContentModel.PROP_NODE_UUID.toString(), false); sp.addSort(ContentModel.PROP_NODE_UUID.toString(), false);
results = searcher.query(sp); results = searcher.query(sp);
assertEquals(15, results.length()); assertEquals(15, results.length());
f = null; f = null;
for (ResultSetRow row : results) for (ResultSetRow row : results)
{ {
@@ -923,9 +920,9 @@ public class ADMLuceneTest extends TestCase
} }
f = currentBun; f = currentBun;
} }
results.close(); results.close();
sp = new SearchParameters(); sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
@@ -933,10 +930,10 @@ public class ADMLuceneTest extends TestCase
sp.addQueryTemplate("ANDY", "%cm:content"); sp.addQueryTemplate("ANDY", "%cm:content");
sp.setNamespace(NamespaceService.CONTENT_MODEL_1_0_URI); sp.setNamespace(NamespaceService.CONTENT_MODEL_1_0_URI);
sp.excludeDataInTheCurrentTransaction(true); sp.excludeDataInTheCurrentTransaction(true);
sp.addSort("@"+ContentModel.PROP_NODE_UUID.toString(), false); sp.addSort("@" + ContentModel.PROP_NODE_UUID.toString(), false);
results = searcher.query(sp); results = searcher.query(sp);
assertEquals(15, results.length()); assertEquals(15, results.length());
f = null; f = null;
for (ResultSetRow row : results) for (ResultSetRow row : results)
{ {
@@ -948,9 +945,9 @@ public class ADMLuceneTest extends TestCase
} }
f = currentBun; f = currentBun;
} }
results.close(); results.close();
sp = new SearchParameters(); sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
@@ -961,7 +958,7 @@ public class ADMLuceneTest extends TestCase
sp.addSort("cm:name", false); sp.addSort("cm:name", false);
results = searcher.query(sp); results = searcher.query(sp);
assertEquals(15, results.length()); assertEquals(15, results.length());
f = null; f = null;
for (ResultSetRow row : results) for (ResultSetRow row : results)
{ {
@@ -973,9 +970,9 @@ public class ADMLuceneTest extends TestCase
} }
f = currentBun; f = currentBun;
} }
results.close(); results.close();
sp = new SearchParameters(); sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.addStore(rootNodeRef.getStoreRef()); sp.addStore(rootNodeRef.getStoreRef());
@@ -987,10 +984,9 @@ public class ADMLuceneTest extends TestCase
results = searcher.query(sp); results = searcher.query(sp);
assertEquals(15, results.length()); assertEquals(15, results.length());
results.close(); results.close();
} }
public void testFTS() throws InterruptedException public void testFTS() throws InterruptedException
{ {
luceneFTS.pause(); luceneFTS.pause();
@@ -3535,27 +3531,27 @@ public class ADMLuceneTest extends TestCase
results.close(); results.close();
// QNames // QNames
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"nine\"", null); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"nine\"", null);
assertEquals(1, results.length()); assertEquals(1, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PRIMARYASSOCTYPEQNAME:\"test:assoc\"", null); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PRIMARYASSOCTYPEQNAME:\"test:assoc\"", null);
assertEquals(10, results.length()); assertEquals(10, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASSOCTYPEQNAME:\"test:assoc\"", null); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASSOCTYPEQNAME:\"test:assoc\"", null);
assertEquals(10, results.length()); assertEquals(10, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PRIMARYASSOCTYPEQNAME:\"sys:children\"", null); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PRIMARYASSOCTYPEQNAME:\"sys:children\"", null);
assertEquals(4, results.length()); assertEquals(4, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASSOCTYPEQNAME:\"sys:children\"", null); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASSOCTYPEQNAME:\"sys:children\"", null);
assertEquals(4, results.length()); assertEquals(4, results.length());
results.close(); results.close();
// Type search tests // Type search tests
QName qname = QName.createQName(TEST_NAMESPACE, "int-ista"); QName qname = QName.createQName(TEST_NAMESPACE, "int-ista");
@@ -3863,115 +3859,120 @@ public class ADMLuceneTest extends TestCase
boolean usesDateTimeAnalyser = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); boolean usesDateTimeAnalyser = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName());
Date date = new Date(); Date date = new Date();
SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); for (SimpleDateFormat df : CachingDateFormat.getLenientFormatters())
String sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
sDate = df.format(testDate);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
// short and long field ranges
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@cm\\:created:[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@cm\\:created:[MIN TO NOW]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(ContentModel.PROP_CREATED) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
// Date ranges
// Test date collapses but date time does not
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[" + sDate + " TO " + sDate + "]",
null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[" + sDate + " TO MAX]", null);
assertEquals(1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene",
"\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + sDate + "]", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO MAX]", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
if (usesDateTimeAnalyser)
{ {
String sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
sDate = df.format(testDate); sDate = df.format(testDate);
// System.out.println("SD = " + sDate);
for (long i : new long[] { 333, 20000, 20 * 60 * 1000, 8 * 60 * 60 * 1000, 10 * 24 * 60 * 60 * 1000, 4 * 30 * 24 * 60 * 60 * 1000, 10 * 12 * 30 * 24 * 60 * 60 * 1000 }) results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null);
assertEquals(1, results.length());
results.close();
// short and long field ranges
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@cm\\:created:[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@cm\\:created:[MIN TO NOW]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(ContentModel.PROP_CREATED) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
// Date ranges
// Test date collapses but date time does not
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene",
"\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[" + sDate + " TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = df.format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[" + sDate + " TO MAX]", null);
assertEquals(1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + sDate + "]", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher
.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[MIN TO " + sDate + "]", null);
assertEquals(1, results.length());
results.close();
sDate = CachingDateFormat.getDateFormat().format(date);
results = searcher
.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO MAX]", null);
assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length());
results.close();
if (usesDateTimeAnalyser)
{ {
String startDate = df.format(new Date(testDate.getTime() - i)); sDate = df.format(testDate);
// System.out.println("\tStart = " + startDate); // System.out.println("SD = " + sDate);
String endDate = df.format(new Date(testDate.getTime() + i)); for (long i : new long[] { 333, 20000, 20 * 60 * 1000, 8 * 60 * 60 * 1000, 10 * 24 * 60 * 60 * 1000, 4 * 30 * 24 * 60 * 60 * 1000,
// System.out.println("\tEnd = " + endDate); 10 * 12 * 30 * 24 * 60 * 60 * 1000 })
{
String startDate = df.format(new Date(testDate.getTime() - i));
// System.out.println("\tStart = " + startDate);
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" String endDate = df.format(new Date(testDate.getTime() + i));
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + endDate + "]", null); // System.out.println("\tEnd = " + endDate);
assertEquals(1, results.length());
results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + endDate + "]", null); + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + endDate + "]", null);
assertEquals(1, results.length()); assertEquals(1, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + sDate + "]", null); + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + endDate + "]", null);
assertEquals(1, results.length()); assertEquals(1, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + sDate + " TO " + endDate + "}", null); + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + sDate + "]", null);
assertEquals(0, results.length()); assertEquals(1, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + startDate + " TO " + sDate + "}", null); + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + sDate + " TO " + endDate + "}", null);
assertEquals(0, results.length()); assertEquals(0, results.length());
results.close(); results.close();
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@"
+ escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + startDate + " TO " + sDate + "}", null);
assertEquals(0, results.length());
results.close();
}
} }
} }

View File

@@ -71,7 +71,6 @@ public class DateTimeTokenFilter extends Tokenizer
public void buildIterator() throws IOException public void buildIterator() throws IOException
{ {
SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true);
Token candidate; Token candidate;
ArrayList<Token> tokens = new ArrayList<Token>(); ArrayList<Token> tokens = new ArrayList<Token>();
while ((candidate = baseTokeniser.next()) != null) while ((candidate = baseTokeniser.next()) != null)
@@ -85,7 +84,7 @@ public class DateTimeTokenFilter extends Tokenizer
{ {
try try
{ {
date = df.parse(candidate.termText()); date = CachingDateFormat.lenientParse(candidate.termText());
} }
catch (ParseException e) catch (ParseException e)
{ {

View File

@@ -50,7 +50,6 @@ public class DateTokenFilter extends Tokenizer
public Token next() throws IOException public Token next() throws IOException
{ {
SimpleDateFormat df = CachingDateFormat.getDateFormat();
SimpleDateFormat dof = CachingDateFormat.getDateOnlyFormat(); SimpleDateFormat dof = CachingDateFormat.getDateOnlyFormat();
Token candidate; Token candidate;
while ((candidate = baseTokeniser.next()) != null) while ((candidate = baseTokeniser.next()) != null)
@@ -64,7 +63,7 @@ public class DateTokenFilter extends Tokenizer
{ {
try try
{ {
date = df.parse(candidate.termText()); date = CachingDateFormat.lenientParse(candidate.termText());
} }
catch (ParseException e) catch (ParseException e)
{ {