Query on date type residual property of nt:unstructured
l.tagliani Apr 12, 2013 5:37 AMHi all,
I'm trying to test the performance of date range query creating a set of 100000 nodes of type nt:unstructured, setting different property on them and then performing the query.
Her's a strip of the code used to create those nodes:
{code}
Session session = repository.login(new SimpleCredentials("admin", "password".toCharArray()), null);
Node testRoot = session.getRootNode().addNode("testDateRangeQueryXPATH", "nt:unstructured");
testRoot.setProperty("nt:name", "testDateRangeQueryXPATH");
session.save();
// create 100000 elements with a property date and a property string
// representing the same date as timestamp in three types:
// nt:date (date)
// nt:dateLong (string)
// nt:dateMiddle (string)
// nt:dateShort (string)
// nt:dateMini (string)
Calendar c = GregorianCalendar.getInstance();
long size = 100000;
SimpleDateFormat sdfMini = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdfShort = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat sdfMiddle = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdfLong = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
DecimalFormat df = new DecimalFormat("000000");
for (int i = 0; i < size; i++) {
Node newNode = testRoot.addNode("node" + df.format(i), "nt:unstructured");
newNode.setProperty("nt:date", c);
newNode.setProperty("nt:dateMini", sdfMini.format(c.getTime()));
newNode.setProperty("nt:dateShort", sdfShort.format(c.getTime()));
newNode.setProperty("nt:dateMiddle", sdfMiddle.format(c.getTime()));
newNode.setProperty("nt:dateLong", sdfLong.format(c.getTime()));
c.add(Calendar.HOUR_OF_DAY, 1);
c.add(Calendar.SECOND, 3);
c.add(Calendar.MILLISECOND, 134);
if (i % 1000 == 0) {
session.save();
logger.info("Saved " + i + " nodes");
}
}
session.save();
logger.info("Saved " + size + " nodes");
// wait for indexing to end
Thread.sleep(5000);
{code}
And here's the code used to perform the query:
{code}
// ±YYYY-MM-DDThh:mm:ss.SSSTZD
String startDate = "2012-03-21T00:00:00.000+01:00";
String endDate = "2016-03-21T23:59:59.999+01:00";
String queryString = "//element(*, nt:unstructured)[@nt:date >=xs:dateTime('" + startDate + "') and @nt:date <=xs:dateTime('" + endDate + "')] order by @jcr:score";
logger.info("Query using date property");
long startTime = System.currentTimeMillis();
nit = qm.createQuery(queryString, Query.XPATH).execute().getNodes();
long endTime = System.currentTimeMillis() - startTime;
logger.info("Retrieved " + nit.getSize() + " in " + endTime + " ms");
logger.info("First element date : " + sdfLong.format(nit.nextNode().getProperty("nt:date").getDate().getTime()));
logger.info("===================================================");
Thread.sleep(5000);
{code}
The query didn't perform at all, with the following execption:
{code}
java.lang.NullPointerException: null
at org.modeshape.jcr.query.lucene.basic.BasicLuceneQueryFactory.findNodesWithNumericRange(BasicLuceneQueryFactory.java:718)
at org.modeshape.jcr.query.lucene.basic.BasicLuceneQueryFactory.findNodesWithNumericRange(BasicLuceneQueryFactory.java:698)
at org.modeshape.jcr.query.lucene.LuceneQueryFactory.createQuery(LuceneQueryFactory.java:366)
at org.modeshape.jcr.query.lucene.LuceneQueryFactory.createQuery(LuceneQueryFactory.java:204)
at org.modeshape.jcr.query.lucene.basic.BasicLuceneSchema.createQuery(BasicLuceneSchema.java:492)
at org.modeshape.jcr.query.lucene.LuceneQueryEngine$LuceneAccessQuery.execute(LuceneQueryEngine.java:269)
at org.modeshape.jcr.query.process.SortValuesComponent.execute(SortValuesComponent.java:65)
at org.modeshape.jcr.query.process.QueryProcessor.execute(QueryProcessor.java:96)
at org.modeshape.jcr.query.process.QueryEngine.execute(QueryEngine.java:140)
at org.modeshape.jcr.query.lucene.LuceneQueryEngine$1.getResults(LuceneQueryEngine.java:153)
at org.modeshape.jcr.query.JcrQuery.execute(JcrQuery.java:119)
at it.cbt.wr.core.service.repository.jcr.modeshape.DateRangeTest.testDateRangeQuerySQL(DateRangeTest.java:138)
{code}
It seems that the Modeshape search component isn't aware of the presence of the nt:date property.
If I perform a query usign e.g. the nt:dateMini property, which actually is a string, using this query string
{code}
//mini (yyyyMMdd)
String miniStartDate = "2012-03-21";
String miniEndDate = "2016-03-21";
String miniQueryString = "//element(*, nt:unstructured)[@nt:dateMini >='" + miniStartDate + "' and @nt:dateMini <='" + miniEndDate + "'] order by @nt:date";
{code}
there isn't any problem.
Is this correct or I've misunderstood something?
BR
Luca