-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ issue #14 ] SPARQL Integration suite works on SOLR too!
- Loading branch information
agazzarini
committed
Aug 28, 2014
1 parent
3defee6
commit e03bf3f
Showing
14 changed files
with
330 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...-binding/jena-nosql-binding-solr/src/main/java/org/gazzax/labs/jena/nosql/solr/Field.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
...jena-nosql-binding-solr/src/main/java/org/gazzax/labs/jena/nosql/solr/NoOpDictionary.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package org.gazzax.labs.jena.nosql.solr; | ||
|
||
import java.util.Iterator; | ||
|
||
import org.gazzax.labs.jena.nosql.fwk.StorageLayerException; | ||
import org.gazzax.labs.jena.nosql.fwk.dictionary.TopLevelDictionary; | ||
import org.gazzax.labs.jena.nosql.fwk.factory.StorageLayerFactory; | ||
|
||
import com.hp.hpl.jena.graph.Node; | ||
import com.hp.hpl.jena.graph.Triple; | ||
import com.hp.hpl.jena.sparql.core.Quad; | ||
|
||
/** | ||
* A NullObject dictionary that, as the name suggests, does nothing. | ||
* | ||
* @author Andrea Gazzarini | ||
* @since 1.0 | ||
*/ | ||
class NoOpDictionary implements TopLevelDictionary { | ||
|
||
@Override | ||
public void close() { | ||
// Nothing to be done here... | ||
} | ||
|
||
@Override | ||
public byte[] getID(Node node, boolean p) throws StorageLayerException { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Node getValue(byte[] id, boolean p) throws StorageLayerException { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public void removeValue(Node value, boolean p) throws StorageLayerException { | ||
// Nothing to be done here... | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public void initialise(final StorageLayerFactory factory) { | ||
// Nothing to be done here... | ||
} | ||
|
||
@Override | ||
public byte[][] asIdentifiers(final Node s, final Node p, final Node o) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public byte[][] asIdentifiers(final Node s, final Node p, final Node o, final Node c) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Triple asTriple(final byte[] s, final byte[] p, final byte[] o) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Quad asQuad(final byte[] s, final byte[] p, final byte[] o, final byte[] c) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean isBNode(final byte[] id) { | ||
// Nothing to be done here... | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isLiteral(final byte[] id) { | ||
// Nothing to be done here... | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isResource(final byte[] id) { | ||
// Nothing to be done here... | ||
return false; | ||
} | ||
|
||
@Override | ||
public Iterator<byte[][]> asTripleIdentifiersIterator(final Iterator<Triple> triples) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Iterator<byte[][]> asQuadIdentifiersIterator(final Iterator<Quad> quads) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Iterator<Triple> asTripleIterator(final Iterator<byte[][]> identifiers) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public Iterator<Quad> asQuadIterator(final Iterator<byte[][]> quads) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public byte[] compose(final byte[] id1, final byte[] id2) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public byte[] compose(final byte[] id1, final byte[] id2, final byte[] id3) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
|
||
@Override | ||
public byte[][] decompose(final byte[] compositeId) { | ||
// Nothing to be done here... | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...inding-solr/src/main/java/org/gazzax/labs/jena/nosql/solr/dao/SolrDeepPagingIterator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package org.gazzax.labs.jena.nosql.solr.dao; | ||
|
||
import java.util.Iterator; | ||
|
||
import org.apache.solr.client.solrj.SolrQuery; | ||
import org.apache.solr.client.solrj.SolrServer; | ||
import org.apache.solr.client.solrj.response.QueryResponse; | ||
import org.apache.solr.common.SolrDocument; | ||
import org.apache.solr.common.SolrDocumentList; | ||
import org.apache.solr.common.params.CursorMarkParams; | ||
import org.gazzax.labs.jena.nosql.fwk.util.NTriples; | ||
import org.gazzax.labs.jena.nosql.solr.Field; | ||
|
||
import com.google.common.collect.UnmodifiableIterator; | ||
import com.hp.hpl.jena.graph.Triple; | ||
|
||
/** | ||
* An iterator over SOLR results that uses the built-in Deep Paging strategy. | ||
* Internally it uses other iterators to represents each iteration state. | ||
* | ||
* @see http://solr.pl/en/2014/03/10/solr-4-7-efficient-deep-paging | ||
* @see http://heliosearch.org/solr/paging-and-deep-paging | ||
* @see <a href="http://en.wikipedia.org/wiki/Finite-state_machine">http://en.wikipedia.org/wiki/Finite-state_machine</a> | ||
* @author Andrea Gazzarini | ||
* @since 1.0 | ||
*/ | ||
public class SolrDeepPagingIterator extends UnmodifiableIterator<Triple> { | ||
|
||
private final SolrServer solr; | ||
private final SolrQuery query; | ||
private SolrDocumentList page; | ||
|
||
private String nextCursorMark; | ||
private String sentCursorMark; | ||
|
||
/** | ||
* Iteration state: we need to (re)execute a query. | ||
* This could be needed the very first time we start iteration and each time the current result | ||
* page has been consumed. | ||
*/ | ||
private final Iterator<Triple> executeQuery = new UnmodifiableIterator<Triple>() { | ||
@Override | ||
public boolean hasNext() { | ||
try { | ||
final QueryResponse response = solr.query(query); | ||
nextCursorMark = response.getNextCursorMark(); | ||
page = response.getResults(); | ||
return page.getNumFound() > 0; | ||
} catch (final Exception exception) { | ||
throw new RuntimeException(exception); | ||
} | ||
} | ||
|
||
@Override | ||
public Triple next() { | ||
currentState = iterateOverCurrentPage; | ||
return currentState.next(); | ||
} | ||
}; | ||
|
||
/** | ||
* Iteration state: query has been executed and now it's time to iterate over results. | ||
*/ | ||
private final Iterator<Triple> iterateOverCurrentPage = new UnmodifiableIterator<Triple>() { | ||
Iterator<SolrDocument> iterator; | ||
|
||
@Override | ||
public boolean hasNext() { | ||
if (iterator().hasNext()) { | ||
return true; | ||
} else { | ||
currentState = checkForIterationCompleteness; | ||
return currentState.hasNext(); | ||
} | ||
} | ||
|
||
@Override | ||
public Triple next() { | ||
final SolrDocument document = iterator().next(); | ||
return Triple.create( | ||
NTriples.asURIorBlankNode((String) document.getFieldValue(Field.S)), | ||
NTriples.asURI((String) document.getFieldValue(Field.P)), | ||
NTriples.asNode((String) document.getFieldValue(Field.O))); | ||
} | ||
|
||
Iterator<SolrDocument> iterator() { | ||
if (iterator == null) { | ||
iterator = page.iterator(); | ||
} | ||
return iterator; | ||
|
||
} | ||
}; | ||
|
||
/** | ||
* Iteration state: once a page has been consumed we need to determine if another query should be issued or not. | ||
*/ | ||
private final Iterator<Triple> checkForIterationCompleteness = new UnmodifiableIterator<Triple>() { | ||
@Override | ||
public boolean hasNext() { | ||
return !(page.size() < query.getRows() || sentCursorMark.equals(nextCursorMark)); | ||
} | ||
|
||
@Override | ||
public Triple next() { | ||
query.set(CursorMarkParams.CURSOR_MARK_PARAM, nextCursorMark); | ||
currentState = executeQuery; | ||
return currentState.next(); | ||
} | ||
}; | ||
|
||
private Iterator<Triple> currentState = executeQuery; | ||
|
||
/** | ||
* Builds a new iterator with the given data. | ||
* | ||
* @param solr the SOLR facade. | ||
* @param query the query that will be submitted. | ||
*/ | ||
public SolrDeepPagingIterator(final SolrServer solr, final SolrQuery query) { | ||
this.solr = solr; | ||
this.query = query; | ||
this.sentCursorMark = CursorMarkParams.CURSOR_MARK_START; | ||
this.query.set(CursorMarkParams.CURSOR_MARK_PARAM, CursorMarkParams.CURSOR_MARK_START); | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
return currentState.hasNext(); | ||
} | ||
|
||
@Override | ||
public Triple next() { | ||
return currentState.next(); | ||
} | ||
} |
Oops, something went wrong.