use of org.neo4j.kernel.api.impl.index.collector.ValuesIterator in project neo4j by neo4j.
the class PageOfRangesIterator method fetchNextOrNull.
@Override
protected PrimitiveLongIterator fetchNextOrNull() {
if (searcher == null) {
// we are done searching with this iterator
return null;
}
ValuesIterator ranges = getRanges();
int pageSize = Math.min(ranges.remaining(), rangesPerPage);
long[] rangeMap = new long[pageSize * 2];
for (int i = 0; i < pageSize; i++) {
long range = ranges.next();
rangeMap[i * 2] = range;
rangeMap[i * 2 + 1] = labeledBitmap(ranges);
}
if (// not a full page => this is the last page (optimization)
pageSize < rangesPerPage) {
// avoid searching again
searcher = null;
}
return new LongPageIterator(new BitmapExtractor(format.bitmapFormat(), rangeMap));
}
use of org.neo4j.kernel.api.impl.index.collector.ValuesIterator in project neo4j by neo4j.
the class ScoreEntityIteratorTest method mergeShouldHandleEmptyIterators.
@Test
void mergeShouldHandleEmptyIterators() {
StubValuesIterator one = new StubValuesIterator();
StubValuesIterator two = new StubValuesIterator().add(1, 5).add(2, 4).add(3, 3).add(4, 2).add(5, 1);
StubValuesIterator three = new StubValuesIterator();
ValuesIterator concat = ScoreEntityIterator.mergeIterators(Arrays.asList(one, two, three));
for (int i = 1; i <= 5; i++) {
assertTrue(concat.hasNext());
assertEquals(i, concat.next());
assertEquals(i, concat.current());
assertEquals(6 - i, concat.currentScore(), 0.001);
}
assertFalse(concat.hasNext());
}
use of org.neo4j.kernel.api.impl.index.collector.ValuesIterator in project neo4j by neo4j.
the class FulltextIndexReader method searchLucene.
private ValuesIterator searchLucene(Query query, IndexQueryConstraints constraints, QueryContext context, CursorContext cursorContext, MemoryTracker memoryTracker) {
try {
// We are replicating the behaviour of IndexSearcher.search(Query, Collector), which starts out by re-writing the query,
// then creates a weight based on the query and index reader context, and then we finally search the leaf contexts with
// the weight we created.
// The query rewrite does not really depend on any data in the index searcher (we don't produce such queries), so it's fine
// that we only rewrite the query once with the first searcher in our partition list.
query = searchers.get(0).getIndexSearcher().rewrite(query);
boolean includeTransactionState = context.getTransactionStateOrNull() != null && !isEventuallyConsistent(index);
// If we have transaction state, then we need to make our result collector filter out all results touched by the transaction state.
// The reason we filter them out entirely, is that we will query the transaction state separately.
LongPredicate filter = includeTransactionState ? transactionState.isModifiedInTransactionPredicate() : ALWAYS_FALSE;
List<PreparedSearch> searches = new ArrayList<>(searchers.size() + 1);
for (SearcherReference searcher : searchers) {
Neo4jIndexSearcher indexSearcher = searcher.getIndexSearcher();
searches.add(new PreparedSearch(indexSearcher, filter));
}
if (includeTransactionState) {
SearcherReference reference = transactionState.maybeUpdate(context, cursorContext, memoryTracker);
searches.add(new PreparedSearch(reference.getIndexSearcher(), ALWAYS_FALSE));
}
// The StatsCollector aggregates index statistics across all our partitions.
// Weights created based on these statistics will produce scores that are comparable across partitions.
StatsCollector statsCollector = new StatsCollector(searches);
List<ValuesIterator> results = new ArrayList<>(searches.size());
for (PreparedSearch search : searches) {
// Weights are bonded with the top IndexReaderContext of the index searcher that they are created for.
// That's why we have to create a new StatsCachingIndexSearcher, and a new weight, for every index partition.
// However, the important thing is that we re-use the statsCollector.
StatsCachingIndexSearcher statsCachingIndexSearcher = new StatsCachingIndexSearcher(search, statsCollector);
Weight weight = statsCachingIndexSearcher.createWeight(query, ScoreMode.COMPLETE, 1);
results.add(search.search(weight, constraints));
}
return ScoreEntityIterator.mergeIterators(results);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of org.neo4j.kernel.api.impl.index.collector.ValuesIterator in project neo4j by neo4j.
the class FulltextIndexReader method query.
@Override
public void query(QueryContext context, IndexProgressor.EntityValueClient client, IndexQueryConstraints constraints, PropertyIndexQuery... queries) throws IndexNotApplicableKernelException {
BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
for (PropertyIndexQuery indexQuery : queries) {
if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.fulltextSearch) {
PropertyIndexQuery.FulltextSearchPredicate fulltextSearch = (PropertyIndexQuery.FulltextSearchPredicate) indexQuery;
try {
queryBuilder.add(parseFulltextQuery(fulltextSearch.query()), BooleanClause.Occur.SHOULD);
} catch (ParseException e) {
throw new RuntimeException("Could not parse the given fulltext search query: '" + fulltextSearch.query() + "'.", e);
}
} else {
// Not fulltext query
assertNotComposite(queries);
assertCypherCompatible();
Query query;
if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringContains) {
PropertyIndexQuery.StringContainsPredicate scp = (PropertyIndexQuery.StringContainsPredicate) indexQuery;
String searchTerm = QueryParser.escape(scp.contains().stringValue());
Term term = new Term(propertyNames[0], "*" + searchTerm + "*");
query = new WildcardQuery(term);
} else if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringSuffix) {
PropertyIndexQuery.StringSuffixPredicate ssp = (PropertyIndexQuery.StringSuffixPredicate) indexQuery;
String searchTerm = QueryParser.escape(ssp.suffix().stringValue());
Term term = new Term(propertyNames[0], "*" + searchTerm);
query = new WildcardQuery(term);
} else if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringPrefix) {
PropertyIndexQuery.StringPrefixPredicate spp = (PropertyIndexQuery.StringPrefixPredicate) indexQuery;
String searchTerm = spp.prefix().stringValue();
Term term = new Term(propertyNames[0], searchTerm);
query = new LuceneDocumentStructure.PrefixMultiTermsQuery(term);
} else if (indexQuery.getClass() == PropertyIndexQuery.ExactPredicate.class && indexQuery.valueGroup() == ValueGroup.TEXT) {
PropertyIndexQuery.ExactPredicate exact = (PropertyIndexQuery.ExactPredicate) indexQuery;
String searchTerm = ((TextValue) exact.value()).stringValue();
Term term = new Term(propertyNames[0], searchTerm);
query = new ConstantScoreQuery(new TermQuery(term));
} else if (indexQuery.getClass() == PropertyIndexQuery.TextRangePredicate.class) {
PropertyIndexQuery.TextRangePredicate sp = (PropertyIndexQuery.TextRangePredicate) indexQuery;
query = newRangeSeekByStringQuery(propertyNames[0], sp.from(), sp.fromInclusive(), sp.to(), sp.toInclusive());
} else {
throw new IndexNotApplicableKernelException("A fulltext schema index cannot answer " + indexQuery.type() + " queries on " + indexQuery.valueCategory() + " values.");
}
queryBuilder.add(query, BooleanClause.Occur.MUST);
}
}
Query query = queryBuilder.build();
ValuesIterator itr = searchLucene(query, constraints, context, context.cursorContext(), context.memoryTracker());
IndexProgressor progressor = new FulltextIndexProgressor(itr, client, constraints);
client.initialize(index, progressor, queries, constraints, true);
}
use of org.neo4j.kernel.api.impl.index.collector.ValuesIterator in project neo4j by neo4j.
the class ScoreEntityIteratorTest method mergeShouldHandleAllEmptyIterators.
@Test
void mergeShouldHandleAllEmptyIterators() {
StubValuesIterator one = new StubValuesIterator();
StubValuesIterator two = new StubValuesIterator();
StubValuesIterator three = new StubValuesIterator();
ValuesIterator concat = ScoreEntityIterator.mergeIterators(Arrays.asList(one, two, three));
assertFalse(concat.hasNext());
}
Aggregations