| /** |
| * 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. |
| */ |
| package org.apache.rya.indexing.mongo; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.rya.api.RdfCloudTripleStoreConfiguration; |
| import org.apache.rya.api.RdfCloudTripleStoreConstants; |
| import org.apache.rya.api.client.Install.InstallConfiguration; |
| import org.apache.rya.api.client.RyaClient; |
| import org.apache.rya.api.client.mongo.MongoConnectionDetails; |
| import org.apache.rya.api.client.mongo.MongoRyaClientFactory; |
| import org.apache.rya.indexing.accumulo.ConfigUtils; |
| import org.apache.rya.mongodb.MongoDBRdfConfiguration; |
| import org.apache.rya.mongodb.MongoRyaITBase; |
| import org.apache.rya.sail.config.RyaSailFactory; |
| import org.eclipse.rdf4j.model.Statement; |
| import org.eclipse.rdf4j.model.ValueFactory; |
| import org.eclipse.rdf4j.model.impl.SimpleValueFactory; |
| import org.eclipse.rdf4j.query.BindingSet; |
| import org.eclipse.rdf4j.query.QueryLanguage; |
| import org.eclipse.rdf4j.query.TupleQuery; |
| import org.eclipse.rdf4j.query.TupleQueryResult; |
| import org.eclipse.rdf4j.query.impl.MapBindingSet; |
| import org.eclipse.rdf4j.repository.sail.SailRepository; |
| import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; |
| import org.eclipse.rdf4j.sail.Sail; |
| import org.junit.Test; |
| |
| public class MongoPCJIndexIT extends MongoRyaITBase { |
| private static final ValueFactory VF = SimpleValueFactory.getInstance(); |
| |
| @Override |
| protected void updateConfiguration(final MongoDBRdfConfiguration conf) { |
| conf.setBoolean(ConfigUtils.USE_MONGO, true); |
| conf.setBoolean(ConfigUtils.USE_PCJ, false); |
| } |
| |
| @Test |
| public void sparqlQuery_Test() throws Exception { |
| // Setup a Rya Client. |
| final MongoConnectionDetails connectionDetails = getConnectionDetails(); |
| final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient()); |
| final String pcjQuery = "SELECT ?name WHERE {" |
| + " ?name <urn:likes> <urn:icecream> ." |
| + " ?name <urn:hasEyeColor> <urn:blue> ." |
| + " }"; |
| |
| // Install an instance of Rya and load statements. |
| ryaClient.getInstall().install(conf.getRyaInstanceName(), InstallConfiguration.builder() |
| .setEnablePcjIndex(true) |
| .build()); |
| ryaClient.getLoadStatements().loadStatements(conf.getRyaInstanceName(), getStatements()); |
| final String pcjId = ryaClient.getCreatePCJ().createPCJ(conf.getRyaInstanceName(), pcjQuery); |
| ryaClient.getBatchUpdatePCJ().batchUpdate(conf.getRyaInstanceName(), pcjId); |
| |
| //purge contents of rya triples collection |
| getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection(conf.getTriplesCollectionName()).drop(); |
| |
| //run the query. since the triples collection is gone, if the results match, they came from the PCJ index. |
| conf.setBoolean(ConfigUtils.USE_PCJ, true); |
| conf.setBoolean(ConfigUtils.USE_OPTIMAL_PCJ, true); |
| conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, true); |
| final Sail sail = RyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| conn.begin(); |
| final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, pcjQuery); |
| tupleQuery.setBinding(RdfCloudTripleStoreConfiguration.CONF_QUERYPLAN_FLAG, RdfCloudTripleStoreConstants.VALUE_FACTORY.createLiteral(true)); |
| final TupleQueryResult rez = tupleQuery.evaluate(); |
| final Set<BindingSet> results = new HashSet<>(); |
| while(rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| |
| // Verify the correct results were loaded into the PCJ table. |
| final Set<BindingSet> expectedResults = new HashSet<>(); |
| |
| MapBindingSet bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Alice")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Bob")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Charlie")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:David")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Eve")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Frank")); |
| expectedResults.add(bs); |
| |
| assertEquals(6, results.size()); |
| assertEquals(expectedResults, results); |
| } |
| |
| @Test |
| public void sparqlQuery_Test_complex() throws Exception { |
| // Setup a Rya Client. |
| final MongoConnectionDetails connectionDetails = getConnectionDetails(); |
| final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient()); |
| final String pcjQuery = "SELECT ?name WHERE {" |
| + " ?name <urn:likes> <urn:icecream> ." |
| + " ?name <urn:hasEyeColor> <urn:blue> ." |
| + " }"; |
| |
| final String testQuery = |
| "SELECT ?name WHERE {" |
| + " ?name <urn:hasHairColor> <urn:brown> ." |
| + " ?name <urn:likes> <urn:icecream> ." |
| + " ?name <urn:hasEyeColor> <urn:blue> ." |
| + " }"; |
| |
| // Install an instance of Rya and load statements. |
| conf.setBoolean(ConfigUtils.USE_PCJ, true); |
| conf.setBoolean(ConfigUtils.USE_OPTIMAL_PCJ, true); |
| conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, true); |
| ryaClient.getInstall().install(conf.getRyaInstanceName(), InstallConfiguration.builder() |
| .setEnablePcjIndex(true) |
| .build()); |
| ryaClient.getLoadStatements().loadStatements(conf.getRyaInstanceName(), getStatements()); |
| final String pcjId = ryaClient.getCreatePCJ().createPCJ(conf.getRyaInstanceName(), pcjQuery); |
| ryaClient.getBatchUpdatePCJ().batchUpdate(conf.getRyaInstanceName(), pcjId); |
| |
| System.out.println("Triples: " + getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection(conf.getTriplesCollectionName()).count()); |
| System.out.println("PCJS: " + getMongoClient().getDatabase(conf.getRyaInstanceName()).getCollection("pcjs").count()); |
| |
| //run the query. since the triples collection is gone, if the results match, they came from the PCJ index. |
| final Sail sail = RyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| conn.begin(); |
| final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, testQuery); |
| tupleQuery.setBinding(RdfCloudTripleStoreConfiguration.CONF_QUERYPLAN_FLAG, RdfCloudTripleStoreConstants.VALUE_FACTORY.createLiteral(true)); |
| final TupleQueryResult rez = tupleQuery.evaluate(); |
| |
| final Set<BindingSet> results = new HashSet<>(); |
| while(rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| |
| // Verify the correct results were loaded into the PCJ table. |
| final Set<BindingSet> expectedResults = new HashSet<>(); |
| |
| MapBindingSet bs = new MapBindingSet(); |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:David")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Eve")); |
| expectedResults.add(bs); |
| |
| bs = new MapBindingSet(); |
| bs.addBinding("name", VF.createIRI("urn:Frank")); |
| expectedResults.add(bs); |
| |
| assertEquals(3, results.size()); |
| assertEquals(expectedResults, results); |
| } |
| |
| private MongoConnectionDetails getConnectionDetails() { |
| final java.util.Optional<char[]> password = conf.getMongoPassword() != null ? |
| java.util.Optional.of(conf.getMongoPassword().toCharArray()) : |
| java.util.Optional.empty(); |
| |
| return new MongoConnectionDetails( |
| conf.getMongoHostname(), |
| Integer.parseInt(conf.getMongoPort()), |
| java.util.Optional.ofNullable(conf.getMongoUser()), |
| password); |
| } |
| |
| private Set<Statement> getStatements() throws Exception { |
| final Set<Statement> statements = new HashSet<>(); |
| statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:likes"), VF.createIRI("urn:icecream"))); |
| |
| statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:green"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:hasEyeColor"), VF.createIRI("urn:brown"))); |
| |
| statements.add(VF.createStatement(VF.createIRI("urn:Alice"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Bob"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Charlie"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blue"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:David"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Eve"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Frank"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:brown"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:George"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blonde"))); |
| statements.add(VF.createStatement(VF.createIRI("urn:Hillary"), VF.createIRI("urn:hasHairColor"), VF.createIRI("urn:blonde"))); |
| return statements; |
| } |
| } |