GeoTemporalMongoDBStorageStrategy extends IndexingMongoDBStorageStrategy { public Document getFilterQuery(final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters) throws GeoTemporalIndexException { final QueryBuilder builder = QueryBuilder.start(); if(!geoFilters.isEmpty()) { final Document[] geo = getGeoObjs(geoFilters); if(!temporalFilters.isEmpty()) { final Document[] temporal = getTemporalObjs(temporalFilters); builder.and(oneOrAnd(geo), oneOrAnd(temporal)); return builder.get(); } else { return oneOrAnd(geo); } } else if(!temporalFilters.isEmpty()) { final Document[] temporal = getTemporalObjs(temporalFilters); return oneOrAnd(temporal); } else { return builder.get(); } } GeoTemporalMongoDBStorageStrategy(); @Override void createIndices(final MongoCollection<Document> coll); Document getFilterQuery(final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters); @Override Document serialize(final RyaStatement ryaStatement);  }
@Test public void emptyFilters_test() throws Exception { final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ }"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_onlyOneGeo() throws Exception { final String query = "PREFIX geo: <http: + "PREFIX geof: <http: + "SELECT ?point ?wkt " + "WHERE { " + " ?point geo:asWKT ?wkt . " + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(VF.createIRI(filter.getURI()), filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(VF.createIRI(filter.getURI()), sps.get(0), Arrays.stream(arguments).toArray()); geoFilters.add(expr); } final List<IndexingExpr> temporalFilters = new ArrayList<>(); final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"location\" : { " + "\"$geoWithin\" : { " + "\"$geometry\" : { " + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , " + "\"type\" : \"Polygon\"" + "}" + "}" + "}" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_onlyGeos() throws Exception { final String query = "PREFIX geo: <http: + "PREFIX geof: <http: + "SELECT ?point ?wkt " + "WHERE { " + " ?point geo:asWKT ?wkt . " + " FILTER(geof:sfIntersects(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) " + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(VF.createIRI(filter.getURI()), filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(VF.createIRI(filter.getURI()), sps.get(0), Arrays.stream(arguments).toArray()); geoFilters.add(expr); } final List<IndexingExpr> temporalFilters = new ArrayList<>(); final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"$and\" : [ { " + "\"location\" : {" + " \"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] ," + " \"type\" : \"Polygon\"" + "}" + "} , { " + "\"location\" : { " + "\"$geoIntersects\" : {" + " \"$geometry\" : {" + " \"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] ," + " \"type\" : \"Polygon\"" + "}" + "}" + "}" + "}]}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_onlyOneTemporal() throws Exception { final String query = "PREFIX time: <http: + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n" + "SELECT ?event ?time " + "WHERE { " + " ?event time:atTime ?time . " + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) . " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(VF.createIRI(filter.getURI()), filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(VF.createIRI(filter.getURI()), sps.get(0), Arrays.stream(arguments).toArray()); temporalFilters.add(expr); } final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"instant\" : {" + "\"$date\" : \"2015-12-30T12:00:00.000Z\"" + "}" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_onlyTemporal() throws Exception { final String query = "PREFIX time: <http: + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n" + "SELECT ?event ?time " + "WHERE { " + " ?event time:atTime ?time . " + " FILTER(tempo:before(?time, \"2015-12-30T12:00:00Z\")) . " + " FILTER(tempo:insideInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(VF.createIRI(filter.getURI()), filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(VF.createIRI(filter.getURI()), sps.get(0), Arrays.stream(arguments).toArray()); temporalFilters.add(expr); } final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"$and\" : [{" + "\"instant\" : {" + "\"$gt\" : {" + "\"$date\" : \"1970-01-01T00:00:00.000Z\"" + "}," + "\"$lt\" : {" + "\"$date\" : \"1970-01-01T00:00:01.000Z\"" + "}," + "}}, {" + "\"instant\" : {" + "\"$lt\" : {" + "\"$date\" : \"2015-12-30T12:00:00.000Z\"" + "}" + "}" + "}]" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_GeoTemporalOneEach() throws Exception { final String query = "PREFIX time: <http: + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n" + "PREFIX geo: <http: + "PREFIX geof: <http: + "SELECT ?event ?time ?point ?wkt " + "WHERE { " + " ?event time:atTime ?time . " + " ?point geo:asWKT ?wkt . " + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) " + " FILTER(tempo:after(?time, \"2015-12-30T12:00:00Z\")) " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final IRI filterURI = VF.createIRI(filter.getURI()); final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), Arrays.stream(arguments).toArray()); if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) { geoFilters.add(expr); } else { temporalFilters.add(expr); } } final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"$and\" : [ { " + "\"location\" : { " + "\"$geoWithin\" : { " + "\"$geometry\" : { " + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , " + "\"type\" : \"Polygon\"" + "}" + "}" + "}" + "} , { " + "\"instant\" : { " + "\"$gt\" : { " + "\"$date\" : \"2015-12-30T12:00:00.000Z\"" + "}" + "}" + "}]" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_GeoTemporalTwoEach() throws Exception { final String query = "PREFIX time: <http: + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n" + "PREFIX geo: <http: + "PREFIX geof: <http: + "SELECT ?event ?time ?point ?wkt " + "WHERE { " + " ?event time:atTime ?time . " + " ?point geo:asWKT ?wkt . " + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) " + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) " + " FILTER(tempo:hasEndInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . " + " FILTER(tempo:beforeInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . " + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final IRI filterIRI = VF.createIRI(filter.getURI()); final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterIRI, filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(filterIRI, sps.get(0), Arrays.stream(arguments).toArray()); if(IndexingFunctionRegistry.getFunctionType(filterIRI) == FUNCTION_TYPE.GEO) { geoFilters.add(expr); } else { temporalFilters.add(expr); } } final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"$and\" : [ { " + "\"$and\" : [ { " + "\"location\" : { " + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , " + "\"type\" : \"Polygon\"" + "}" + "} , { " + "\"location\" : { " + "\"$geoWithin\" : { " + "\"$geometry\" : { " + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , " + "\"type\" : \"Polygon\"" + "}" + "}" + "}" + "}]" + "} , { " + "\"$and\" : [ { " + "\"instant\" : { " + "\"$lt\" : { " + "\"$date\" : \"1970-01-01T00:00:00.000Z\"" + "}" + "}" + "} , { " + "\"instant\" : { " + "\"$date\" : \"1970-01-01T00:00:01.000Z\"" + "}" + "}]" + "}]" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }
@Test public void equalsInstantAfterInterval_GeoTemporalSingleGeoTwoTemporal() throws Exception { final String query = "PREFIX time: <http: + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n" + "PREFIX geo: <http: + "PREFIX geof: <http: + "SELECT ?event ?time ?point ?wkt " + "WHERE { " + " ?event time:atTime ?time . " + " ?point geo:asWKT ?wkt . " + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) ." + " FILTER(tempo:hasBeginningInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . " + " FILTER(tempo:afterInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\"))" + "}"; final List<IndexingExpr> geoFilters = new ArrayList<>(); final List<IndexingExpr> temporalFilters = new ArrayList<>(); final List<StatementPattern> sps = getSps(query); final List<FunctionCall> filters = getFilters(query); for(final FunctionCall filter : filters) { final IRI filterURI = VF.createIRI(filter.getURI()); final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs()); final Value[] arguments = extractArguments(objVar.getName(), filter); final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), Arrays.stream(arguments).toArray()); if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) { geoFilters.add(expr); } else { temporalFilters.add(expr); } } final Document actual = adapter.getFilterQuery(geoFilters, temporalFilters); final String expectedString = "{ " + "\"$and\" : [ { " + "\"location\" : { " + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , " + "\"type\" : \"Polygon\"" + "}" + "} , { " + "\"$and\" : [ { " + "\"instant\" : { " + "\"$gt\" : { " + "\"$date\" : \"1970-01-01T00:00:01.000Z\"" + "}" + "}" + "} , { " + "\"instant\" : { " + "\"$date\" : \"1970-01-01T00:00:00.000Z\"" + "}" + "}]" + "}]" + "}"; final Document expected = Document.parse(expectedString); assertEqualMongo(expected, actual); }