blob: 5a7598e164a0f3666410c91ad6cccd965eda7b55 [file] [log] [blame]
package org.apache.rya.indexing.mongo;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import static org.apache.rya.api.resolver.RdfToRyaConversions.convertStatement;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.rya.indexing.StatementConstraints;
import org.apache.rya.indexing.TemporalInstant;
import org.apache.rya.indexing.TemporalInstantRfc3339;
import org.apache.rya.indexing.TemporalInterval;
import org.apache.rya.indexing.accumulo.ConfigUtils;
import org.apache.rya.indexing.mongodb.temporal.MongoTemporalIndexer;
import org.apache.rya.mongodb.MongoDBRdfConfiguration;
import org.apache.rya.mongodb.MongoITBase;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.query.QueryEvaluationException;
import org.junit.Test;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.MongoSecurityException;
/**
* JUnit tests for TemporalIndexer and it's implementation MongoTemporalIndexer
*
* If you enjoy this test, please read RyaTemporalIndexerTest and YagoKBTest, which contain
* many example SPARQL queries and updates and attempts to test independently of Mongo:
*
* extras/indexingSail/src/test/java/org.apache/rya/indexing/Mongo/RyaTemporalIndexerTest.java
* {@link org.apache.rya.indexing.Mongo.RyaTemporalIndexerTest}
* {@link org.apache.rya.indexing.Mongo.YagoKBTest.java}
*
* Remember, this class in instantiated fresh for each @test method.
* so fields are reset, unless they are static.
*
* These are covered:
* Instance {before, equals, after} given Instance
* Instance {before, after, inside} given Interval
* Instance {hasBeginning, hasEnd} given Interval
* And a few more.
*
*/
public final class MongoTemporalIndexerIT extends MongoITBase {
private static final String URI_PROPERTY_EVENT_TIME = "Property:event:time";
private static final String URI_PROPERTY_CIRCA = "Property:circa";
private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints();
// Assign this in setUpBeforeClass, store them in each test.
// setup() deletes table before each test.
static final Statement spo_B00_E01;
static final Statement spo_B03_E20;
static final Statement spo_B02_E29;
static final Statement spo_B02_E30;
static final Statement spo_B02_E40;
static final Statement spo_B02_E31;
static final Statement spo_B29_E30;
static final Statement spo_B30_E32;
// Instants:
static final Statement spo_B02;
static final int SERIES_OF_SECONDS = 41;
static final Statement seriesSpo[] = new Statement[SERIES_OF_SECONDS];
// These are shared for several tests. Only the seconds are different.
// tvB03_E20 read as: interval Begins 3 seconds, ends at 20 seconds
static final TemporalInterval tvB00_E01 = new TemporalInterval(makeInstant(00), makeInstant(01));
static final TemporalInterval tvB29_E30= new TemporalInterval(makeInstant(29), makeInstant(30));
static final TemporalInterval tvB30_E32= new TemporalInterval(makeInstant(30), makeInstant(32));
static final TemporalInterval tvB03_E20 = new TemporalInterval(makeInstant(03), makeInstant(20));
// 30 seconds, Begins earlier, ends later
static final TemporalInterval tvB02_E30= new TemporalInterval(makeInstant(02), makeInstant(30));
// use for interval after
static final TemporalInterval tvB02_E29= new TemporalInterval(makeInstant(02), makeInstant(29));
// same as above, but ends in the middle
static final TemporalInterval tvB02_E31 = new TemporalInterval(makeInstant(02), makeInstant(31));
// same as above, but ends even later
static final TemporalInterval tvB02_E40 = new TemporalInterval(makeInstant(02), makeInstant(40));
// instant, match beginnings of several above, before tiB03_E20
static final TemporalInstant tsB02 = makeInstant(02);
// instant, after all above
static final TemporalInstant tsB04 = makeInstant(04);
// Create a series of instants about times 0 - 40 seconds
static final TemporalInstant seriesTs[];
static {
seriesTs = new TemporalInstant[SERIES_OF_SECONDS];
for (int i = 0; i <= 40; i++) {
seriesTs[i] = makeInstant(i);
}
};
/**
* Make an uniform instant with given seconds.
*/
static TemporalInstant makeInstant(final int secondsMakeMeUnique) {
return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, secondsMakeMeUnique);
}
static {
// Setup the statements only once. Each test will store some of these in there own index table.
final ValueFactory vf = SimpleValueFactory.getInstance();
final IRI pred1_atTime = vf.createIRI(URI_PROPERTY_AT_TIME);
// tiB03_E20 read as: time interval that Begins 3 seconds, ends at 20 seconds,
// Each time element the same, except seconds. year, month, .... minute are the same for each statement below.
spo_B00_E01 = vf.createStatement(vf.createIRI("foo:event0"), pred1_atTime, vf.createLiteral(tvB00_E01.toString()));
spo_B02_E29 = vf.createStatement(vf.createIRI("foo:event2"), pred1_atTime, vf.createLiteral(tvB02_E29.toString()));
spo_B02_E30 = vf.createStatement(vf.createIRI("foo:event2"), pred1_atTime, vf.createLiteral(tvB02_E30.toString()));
spo_B02_E31 = vf.createStatement(vf.createIRI("foo:event3"), pred1_atTime, vf.createLiteral(tvB02_E31.toString()));
spo_B02_E40 = vf.createStatement(vf.createIRI("foo:event4"), pred1_atTime, vf.createLiteral(tvB02_E40.toString()));
spo_B03_E20 = vf.createStatement(vf.createIRI("foo:event5"), pred1_atTime, vf.createLiteral(tvB03_E20.toString()));
spo_B29_E30 = vf.createStatement(vf.createIRI("foo:event1"), pred1_atTime, vf.createLiteral(tvB29_E30.toString()));
spo_B30_E32 = vf.createStatement(vf.createIRI("foo:event1"), pred1_atTime, vf.createLiteral(tvB30_E32.toString()));
spo_B02 = vf.createStatement(vf.createIRI("foo:event6"), pred1_atTime, vf.createLiteral(tsB02.getAsReadable()));
// Create statements about time instants 0 - 40 seconds
for (int i = 0; i < seriesTs.length; i++) {
seriesSpo[i] = vf.createStatement(vf.createIRI("foo:event0" + i), pred1_atTime, vf.createLiteral(seriesTs[i].getAsReadable()));
}
}
@Override
protected void updateConfiguration(final MongoDBRdfConfiguration conf) {
// This is from http://linkedevents.org/ontology
// and http://motools.sourceforge.net/event/event.html
conf.setStrings(ConfigUtils.TEMPORAL_PREDICATES_LIST, ""
+ URI_PROPERTY_AT_TIME + ","
+ URI_PROPERTY_CIRCA + ","
+ URI_PROPERTY_EVENT_TIME);
}
/**
* Test method for {@link MongoTemporalIndexer#storeStatement(convertStatement(org.eclipse.rdf4j.model.Statement)}
*/
@Test
public void testStoreStatement() throws IOException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
final ValueFactory vf = SimpleValueFactory.getInstance();
final IRI pred1_atTime = vf.createIRI(URI_PROPERTY_AT_TIME);
final IRI pred2_circa = vf.createIRI(URI_PROPERTY_CIRCA);
// Should not be stored because they are not in the predicate list
final String validDateStringWithThirteens = "1313-12-13T13:13:13Z";
tIndexer.storeStatement(convertStatement(vf.createStatement(vf.createIRI("foo:subj1"), RDFS.LABEL, vf.createLiteral(validDateStringWithThirteens))));
final String invalidDateString = "ThisIsAnInvalidDate";
tIndexer.storeStatement(convertStatement(vf.createStatement(vf.createIRI("foo:subj2"), pred1_atTime, vf.createLiteral(invalidDateString))));
// These are different datetimes instant but from different time zones.
// This is an arbitrary zone, BRST=Brazil, better if not local.
// same as "2015-01-01T01:59:59Z"
final String testDate2014InBRST = "2014-12-31T23:59:59-02:00";
// next year, same as "2017-01-01T01:59:59Z"
final String testDate2016InET = "2016-12-31T20:59:59-05:00";
// These should be stored because they are in the predicate list.
// BUT they will get converted to the same exact datetime in UTC.
final Statement s3 = vf.createStatement(vf.createIRI("foo:subj3"), pred1_atTime, vf.createLiteral(testDate2014InBRST));
final Statement s4 = vf.createStatement(vf.createIRI("foo:subj4"), pred2_circa, vf.createLiteral(testDate2016InET));
tIndexer.storeStatement(convertStatement(s3));
tIndexer.storeStatement(convertStatement(s4));
// This should not be stored because the object is not a literal
tIndexer.storeStatement(convertStatement(vf.createStatement(vf.createIRI("foo:subj5"), pred1_atTime, vf.createIRI("in:valid"))));
printTables(tIndexer, "junit testing: Temporal entities stored in testStoreStatement");
assertEquals(2, tIndexer.getCollection().find().count());
}
}
@Test
public void testDelete() throws IOException, MongoException, TableNotFoundException, TableExistsException, NoSuchAlgorithmException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
final ValueFactory vf = SimpleValueFactory.getInstance();
final IRI pred1_atTime = vf.createIRI(URI_PROPERTY_AT_TIME);
final IRI pred2_circa = vf.createIRI(URI_PROPERTY_CIRCA);
final String testDate2014InBRST = "2014-12-31T23:59:59-02:00";
final String testDate2016InET = "2016-12-31T20:59:59-05:00";
// These should be stored because they are in the predicate list.
// BUT they will get converted to the same exact datetime in UTC.
final Statement s1 = vf.createStatement(vf.createIRI("foo:subj3"), pred1_atTime, vf.createLiteral(testDate2014InBRST));
final Statement s2 = vf.createStatement(vf.createIRI("foo:subj4"), pred2_circa, vf.createLiteral(testDate2016InET));
tIndexer.storeStatement(convertStatement(s1));
tIndexer.storeStatement(convertStatement(s2));
final String dbName = conf.getMongoDBName();
final DB db = super.getMongoClient().getDB(dbName);
DBCollection collection = db.getCollection(conf.get(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya") + tIndexer.getCollectionName());
printTables(tIndexer, "junit testing: Temporal entities stored in testDelete before delete");
assertEquals("Number of rows stored.", 2, collection.count()); // 4 index entries per statement
tIndexer.deleteStatement(convertStatement(s1));
tIndexer.deleteStatement(convertStatement(s2));
printTables(tIndexer, "junit testing: Temporal entities stored in testDelete after delete");
assertEquals("Number of rows stored after delete.", 0, collection.count());
}
}
/**
* Test instant after a given instant.
* From the series: instant {equal, before, after} instant
* @throws MongoSecurityException
* @throws MongoException
* @throws TableNotFoundException
*/
@Test
public void testQueryInstantAfterInstant() throws IOException, QueryEvaluationException, TableNotFoundException, MongoException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instant for s seconds after the uniform time.
final int searchForSeconds = 4;
final int expectedResultCount = 9;
for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) { // <== logic here
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantAfterInstant(seriesTs[searchForSeconds], EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[searchForSeconds + count + 1]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant before a given instant.
* From the series: instant {equal, before, after} instant
*/
@Test
public void testQueryInstantBeforeInstant() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instant for s seconds after the uniform time.
final int searchForSeconds = 4;
final int expectedResultCount = 4;
for (int s = 0; s <= searchForSeconds + 15; s++) { // <== logic here
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantBeforeInstant(seriesTs[searchForSeconds], EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[count]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant before given interval.
* From the series: Instance {before, after, inside} given Interval
*/
@Test
public void testQueryInstantBeforeInterval() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instants for s seconds after the uniform time.
final TemporalInterval searchForSeconds = tvB02_E31;
final int expectedResultCount = 2; // 00 and 01 seconds.
for (int s = 0; s <= 40; s++) { // <== logic here
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantBeforeInterval(searchForSeconds, EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[count]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant after given interval.
* Instance {before, after, inside} given Interval
*/
@Test
public void testQueryInstantAfterInterval() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instants for s seconds after the uniform time.
final TemporalInterval searchAfterInterval = tvB02_E31; // from 2 to 31 seconds
final int endingSeconds = 31;
final int expectedResultCount = 9; // 32,33,...,40 seconds.
for (int s = 0; s <= endingSeconds + expectedResultCount; s++) { // <== logic here
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantAfterInterval(searchAfterInterval, EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[count + endingSeconds + 1]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant inside given interval.
* Instance {before, after, inside} given Interval
*/
@Test
public void testQueryInstantInsideInterval() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instants for s seconds after the uniform time.
final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 to 31 seconds
final int beginningSeconds = 2; // <== logic here, and next few lines.
final int endingSeconds = 31;
final int expectedResultCount = endingSeconds - beginningSeconds - 1; // 3,4,...,30 seconds.
for (int s = 0; s <= 40; s++) {
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantInsideInterval(searchInsideInterval, EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[count + beginningSeconds + 1]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant is the Beginning of the given interval.
* from the series: Instance {hasBeginning, hasEnd} Interval
*/
@Test
public void testQueryInstantHasBeginningInterval() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instants for s seconds after the uniform time.
final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 to 31 seconds
final int searchSeconds = 2; // <== logic here, and next few lines.
final int expectedResultCount = 1; // 2 seconds.
for (int s = 0; s <= 10; s++) {
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantHasBeginningInterval(searchInsideInterval, EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[searchSeconds]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test instant is the end of the given interval.
* from the series: Instance {hasBeginning, hasEnd} Interval
*/
@Test
public void testQueryInstantHasEndInterval() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instants for s seconds after the uniform time.
final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 to 31 seconds
final int searchSeconds = 31; // <== logic here, and next few lines.
final int expectedResultCount = 1; // 31 seconds.
for (int s = 0; s <= 40; s++) {
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryInstantHasEndInterval(searchInsideInterval, EMPTY_CONSTRAINTS);
int count = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[searchSeconds]; // <== logic here
assertTrue("Should match: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count++;
}
assertEquals("Should find count of rows.", expectedResultCount, count);
}
}
/**
* Test method for
* {@link org.apache.rya.indexing.Mongo.temporal.MongoTemporalIndexer#queryIntervalEquals(TemporalInterval, StatementConstraints)}
* .
* @throws IOException
* @throws QueryEvaluationException
*
*/
@Test
public void testQueryIntervalEquals() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
tIndexer.storeStatement(convertStatement(seriesSpo[4])); // instance at 4 seconds
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryIntervalEquals(tvB02_E40, EMPTY_CONSTRAINTS);
// Should be found twice:
assertTrue("queryIntervalEquals: spo_B02_E40 should be found, but actually returned empty results. spo_B02_E40=" + spo_B02_E40, iter.hasNext());
assertTrue("queryIntervalEquals: spo_B02_E40 should be found, but does not match.", spo_B02_E40.equals(iter.next()));
assertFalse("queryIntervalEquals: Find no more than one, but actually has more.", iter.hasNext());
}
}
/**
* Test interval before a given interval, for method:
* {@link MongoTemporalIndexer#queryIntervalBefore(TemporalInterval, StatementConstraints)}.
*
* @throws IOException
* @throws QueryEvaluationException
*/
@Test
public void testQueryIntervalBefore() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
tIndexer.storeStatement(convertStatement(spo_B00_E01));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B03_E20));
// instants should be ignored.
tIndexer.storeStatement(convertStatement(spo_B30_E32));
tIndexer.storeStatement(convertStatement(seriesSpo[1])); // instance at 1 seconds
tIndexer.storeStatement(convertStatement(seriesSpo[2]));
tIndexer.storeStatement(convertStatement(seriesSpo[31]));
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryIntervalBefore(tvB02_E31, EMPTY_CONSTRAINTS);
// Should be found twice:
assertTrue("spo_B00_E01 should be found, but actually returned empty results. spo_B00_E01=" + spo_B00_E01, iter.hasNext());
assertTrue("spo_B00_E01 should be found, but found another.", spo_B00_E01.equals(iter.next()));
assertFalse("Find no more than one, but actually has more.", iter.hasNext());
}
}
/**
* interval is after the given interval. Find interval beginnings after the endings of the given interval.
* {@link MongoTemporalIndexer#queryIntervalAfter(TemporalInterval, StatementContraints).
*
* @throws IOException
* @throws QueryEvaluationException
*/
@Test
public void testQueryIntervalAfter() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
tIndexer.storeStatement(convertStatement(spo_B00_E01));
tIndexer.storeStatement(convertStatement(spo_B02_E29)); //<- after this one.
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B29_E30));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// instants should be ignored.
tIndexer.storeStatement(convertStatement(spo_B02));
tIndexer.storeStatement(convertStatement(seriesSpo[1])); // instance at 1 seconds
tIndexer.storeStatement(convertStatement(seriesSpo[2]));
tIndexer.storeStatement(convertStatement(seriesSpo[31]));
CloseableIteration<Statement, QueryEvaluationException> iter;
iter = tIndexer.queryIntervalAfter(tvB02_E29, EMPTY_CONSTRAINTS);
// Should be found twice:
assertTrue("spo_B30_E32 should be found, but actually returned empty results. spo_B30_E32=" + spo_B30_E32, iter.hasNext());
final Statement s = iter.next();
assertTrue("spo_B30_E32 should be found, but found another. spo_B30_E32="+spo_B30_E32+", but found="+s, spo_B30_E32.equals(s));
assertFalse("Find no more than one, but actually has more.", iter.hasNext());
}
}
/**
* Test instant after a given instant WITH two different predicates as constraints.
*/
@Test
public void testQueryWithMultiplePredicates() throws IOException, QueryEvaluationException {
try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
tIndexer.setConf(conf);
tIndexer.init();
// tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
// these should not match as they are not instances.
tIndexer.storeStatement(convertStatement(spo_B03_E20));
tIndexer.storeStatement(convertStatement(spo_B02_E30));
tIndexer.storeStatement(convertStatement(spo_B02_E40));
tIndexer.storeStatement(convertStatement(spo_B02_E31));
tIndexer.storeStatement(convertStatement(spo_B30_E32));
// seriesSpo[s] and seriesTs[s] are statements and instant for s seconds after the uniform time.
final int searchForSeconds = 4;
final int expectedResultCount = 9;
for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) { // <== logic here
tIndexer.storeStatement(convertStatement(seriesSpo[s]));
}
final ValueFactory vf = SimpleValueFactory.getInstance();
final IRI pred3_CIRCA_ = vf.createIRI(URI_PROPERTY_CIRCA); // this one to ignore.
final IRI pred2_eventTime = vf.createIRI(URI_PROPERTY_EVENT_TIME);
final IRI pred1_atTime = vf.createIRI(URI_PROPERTY_AT_TIME);
// add the predicate = EventTime ; Store in an array for verification.
final Statement[] SeriesTs_EventTime = new Statement[expectedResultCount+1];
for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) { // <== logic here
final Statement statement = vf.createStatement(vf.createIRI("foo:EventTimeSubj0" + s), pred2_eventTime, vf.createLiteral(seriesTs[s].getAsReadable()));
tIndexer.storeStatement(convertStatement(statement));
if (s>searchForSeconds) {
SeriesTs_EventTime[s - searchForSeconds -1 ] = statement;
}
}
// add the predicate = CIRCA ; to be ignored because it is not in the constraints.
for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) { // <== logic here
final Statement statement = vf.createStatement(vf.createIRI("foo:CircaEventSubj0" + s), pred3_CIRCA_, vf.createLiteral(seriesTs[s].getAsReadable()));
tIndexer.storeStatement(convertStatement(statement));
}
CloseableIteration<Statement, QueryEvaluationException> iter;
final StatementConstraints constraints = new StatementConstraints();
constraints.setPredicates(new HashSet<>(Arrays.asList( pred2_eventTime, pred1_atTime )));
iter = tIndexer.queryInstantAfterInstant(seriesTs[searchForSeconds], constraints); // EMPTY_CONSTRAINTS);//
int count_AtTime = 0;
int count_EventTime = 0;
while (iter.hasNext()) {
final Statement s = iter.next();
final Statement nextExpectedStatement = seriesSpo[searchForSeconds + count_AtTime + 1]; // <== logic here
if (s.getPredicate().equals(pred1_atTime)) {
assertTrue("Should match atTime: " + nextExpectedStatement + " == " + s, nextExpectedStatement.equals(s));
count_AtTime++;
}
else if (s.getPredicate().equals(pred2_eventTime)) {
assertTrue("Should match eventTime: " + SeriesTs_EventTime[count_EventTime] + " == " + s, SeriesTs_EventTime[count_EventTime].equals(s));
count_EventTime++;
} else {
assertTrue("This predicate should not be returned: "+s, false);
}
}
assertEquals("Should find count of atTime rows.", expectedResultCount, count_AtTime);
assertEquals("Should find count of eventTime rows.", expectedResultCount, count_EventTime);
}
}
/**
* Print and gather statistics on the entire index table.
*
* @param description
* Printed to the console to find the test case.
* @param out
* null or System.out or other output to send a listing.
* @param statistics
* Hashes, sums, and counts for assertions.
* @return Count of entries in the index table.
* @throws IOException
*/
public void printTables(MongoTemporalIndexer tIndexer, final String description) throws IOException {
System.out.println("-- start printTables() -- " + description);
System.out.println("Reading : " + tIndexer.getCollection().getFullName());
final DBCursor cursor = tIndexer.getCollection().find();
while(cursor.hasNext()) {
final DBObject dbo = cursor.next();
System.out.println(dbo.toString());
}
System.out.println();
}
}