CavalliumDBEngine/src/test/java/it/cavallium/dbengine/lucene/searcher/LuceneGeneratorTest.java

220 lines
7.6 KiB
Java
Raw Normal View History

2022-02-11 21:08:23 +01:00
package it.cavallium.dbengine.lucene.searcher;
import it.cavallium.dbengine.lucene.ExponentialPageLimits;
import it.unimi.dsi.fastutil.longs.LongList;
import java.io.IOException;
import java.time.Duration;
2022-02-12 00:10:56 +01:00
import java.util.Comparator;
2022-02-11 21:08:23 +01:00
import java.util.List;
2022-02-12 00:10:56 +01:00
import java.util.Objects;
2022-02-11 21:08:23 +01:00
import java.util.stream.Collectors;
2022-02-12 00:10:56 +01:00
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
2022-02-11 21:08:23 +01:00
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.StringField;
2022-02-12 00:10:56 +01:00
import org.apache.lucene.document.TextField;
2022-02-11 21:08:23 +01:00
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
2022-02-12 00:10:56 +01:00
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
2022-02-11 21:08:23 +01:00
import org.apache.lucene.search.CustomHitsThresholdChecker;
import org.apache.lucene.search.IndexSearcher;
2022-02-12 00:10:56 +01:00
import org.apache.lucene.search.Query;
2022-02-11 21:08:23 +01:00
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.ByteBuffersDirectory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class LuceneGeneratorTest {
private static IndexSearcher is;
private static ExponentialPageLimits pageLimits;
2022-02-12 00:10:56 +01:00
private static IndexWriter iw;
2022-02-11 21:08:23 +01:00
@BeforeAll
public static void beforeAll() throws IOException {
ByteBuffersDirectory dir = new ByteBuffersDirectory();
2022-02-12 00:10:56 +01:00
Analyzer analyzer = new StandardAnalyzer();
iw = new IndexWriter(dir, new IndexWriterConfig(analyzer));
2022-02-11 21:08:23 +01:00
iw.addDocument(List.of(new LongPoint("position", 1, 1)));
iw.addDocument(List.of(new LongPoint("position", 2, 3)));
iw.addDocument(List.of(new LongPoint("position", 4, -1)));
iw.addDocument(List.of(new LongPoint("position", 3, -54)));
// Exactly 4 dummies
iw.addDocument(List.<IndexableField>of(new StringField("dummy", "dummy", Store.NO)));
iw.addDocument(List.<IndexableField>of(new StringField("dummy", "dummy", Store.NO)));
iw.addDocument(List.<IndexableField>of(new StringField("dummy", "dummy", Store.NO)));
iw.addDocument(List.<IndexableField>of(new StringField("dummy", "dummy", Store.NO)));
2022-02-12 00:10:56 +01:00
// texts
iw.addDocument(List.<IndexableField>of(new TextField("text", "prova abc", Store.YES)));
iw.addDocument(List.<IndexableField>of(new TextField("text", "prova mario", Store.YES)));
iw.addDocument(List.<IndexableField>of(new TextField("text", "luigi provi def", Store.YES)));
iw.addDocument(List.<IndexableField>of(new TextField("text", "abc provo prova", Store.YES)));
iw.addDocument(List.<IndexableField>of(new TextField("text", "prova abd", Store.YES)));
iw.addDocument(List.<IndexableField>of(new TextField("text", "la prova abc def", Store.YES)));
2022-02-11 21:08:23 +01:00
iw.commit();
DirectoryReader ir = DirectoryReader.open(iw);
is = new IndexSearcher(ir);
pageLimits = new ExponentialPageLimits();
}
@Test
2022-02-12 00:10:56 +01:00
public void testPosition() throws IOException {
2022-02-11 21:08:23 +01:00
var query = LongPoint.newRangeQuery("position",
LongList.of(1, -1).toLongArray(),
LongList.of(2, 3).toLongArray()
);
int limit = Integer.MAX_VALUE;
2022-02-12 00:10:56 +01:00
var localQueryParams = new LocalQueryParams(query, 0, limit, pageLimits, Duration.ofDays(1));
2022-02-11 21:08:23 +01:00
2022-02-12 00:10:56 +01:00
var expectedResults = fixResults(localQueryParams.isSorted(),
localQueryParams.needsScores(), List.of(is.search(query, limit).scoreDocs));
2022-02-11 21:08:23 +01:00
2022-02-12 00:10:56 +01:00
var reactiveGenerator = LuceneGenerator.reactive(is, localQueryParams, -1);
var results = fixResults(localQueryParams.isSorted(),
localQueryParams.needsScores(), reactiveGenerator.collectList().block());
Assertions.assertNotEquals(0, results.size());
Assertions.assertEquals(expectedResults, results);
}
@Test
public void testTextSearch() throws IOException, ParseException {
QueryParser queryParser = new QueryParser("text", iw.getAnalyzer());
Query query = queryParser.parse("prova~10 abc~10");
int limit = Integer.MAX_VALUE;
var localQueryParams = new LocalQueryParams(query, 0, limit, pageLimits, Duration.ofDays(1));
var expectedResults = fixResults(localQueryParams.isSorted(),
localQueryParams.needsScores(), List.of(is.search(query, limit).scoreDocs));
var reactiveGenerator = LuceneGenerator.reactive(is, localQueryParams, -1);
var results = fixResults(localQueryParams.isSorted(), localQueryParams.needsScores(), reactiveGenerator.collectList().block());
2022-02-11 21:08:23 +01:00
Assertions.assertNotEquals(0, results.size());
Assertions.assertEquals(expectedResults, results);
}
@Test
public void testLimit0() {
var query = LongPoint.newRangeQuery("position",
LongList.of(1, -1).toLongArray(),
LongList.of(2, 3).toLongArray()
);
var limitThresholdChecker = CustomHitsThresholdChecker.create(0);
var reactiveGenerator = LuceneGenerator.reactive(is,
new LocalQueryParams(query,
0L,
0,
pageLimits,
2022-02-11 21:46:05 +01:00
null,
null,
2022-02-11 21:08:23 +01:00
Duration.ofDays(1)
),
2022-02-11 21:46:05 +01:00
-1
2022-02-11 21:08:23 +01:00
);
var results = reactiveGenerator.collectList().block();
Assertions.assertNotNull(results);
Assertions.assertEquals(0, results.size());
}
@Test
public void testLimitRestrictingResults() {
var query = new TermQuery(new Term("dummy", "dummy"));
int limit = 3; // the number of dummies - 1
var reactiveGenerator = LuceneGenerator.reactive(is,
new LocalQueryParams(query,
0L,
limit,
pageLimits,
null,
2022-02-11 21:46:05 +01:00
null,
2022-02-11 21:08:23 +01:00
Duration.ofDays(1)
),
2022-02-11 21:46:05 +01:00
-1
2022-02-11 21:08:23 +01:00
);
var results = reactiveGenerator.collectList().block();
Assertions.assertNotNull(results);
Assertions.assertEquals(limit, results.size());
}
@Test
public void testDummies() throws IOException {
var query = new TermQuery(new Term("dummy", "dummy"));
int limit = Integer.MAX_VALUE;
2022-02-12 00:10:56 +01:00
var localQueryParams = new LocalQueryParams(query, 0, limit, pageLimits, null, true, Duration.ofDays(1));
2022-02-11 21:08:23 +01:00
2022-02-12 00:10:56 +01:00
var expectedResults = fixResults(localQueryParams.isSorted(), localQueryParams.needsScores(),
List.of(is.search(query, limit, Sort.INDEXORDER, false).scoreDocs));
2022-02-11 21:08:23 +01:00
2022-02-11 22:14:54 +01:00
var reactiveGenerator = LuceneGenerator.reactive(is, localQueryParams, -1);
2022-02-12 00:10:56 +01:00
var results = fixResults(localQueryParams.isSorted(),
localQueryParams.needsScores(), reactiveGenerator.collectList().block());
2022-02-11 21:08:23 +01:00
Assertions.assertEquals(4, results.size());
2022-02-12 00:10:56 +01:00
Assertions.assertEquals(expectedResults, results);
2022-02-11 21:08:23 +01:00
}
2022-02-12 00:10:56 +01:00
private List<ScoreDoc> fixResults(boolean sorted, boolean needsScores, List<ScoreDoc> results) {
2022-02-11 21:08:23 +01:00
Assertions.assertNotNull(results);
2022-02-12 00:10:56 +01:00
var s = results.stream().map(scoreDoc -> needsScores ? new MyScoreDoc(scoreDoc) : new UnscoredScoreDoc(scoreDoc));
if (!sorted) {
s = s.sorted(Comparator.comparingInt(d -> d.doc));
}
return s.collect(Collectors.toList());
2022-02-11 21:08:23 +01:00
}
private static class MyScoreDoc extends ScoreDoc {
public MyScoreDoc(ScoreDoc scoreDoc) {
super(scoreDoc.doc, scoreDoc.score, scoreDoc.shardIndex);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof ScoreDoc sd) {
2022-02-12 00:10:56 +01:00
return Objects.equals(this.score, sd.score)
&& Objects.equals(this.doc, sd.doc)
&& this.shardIndex == sd.shardIndex;
}
return false;
}
}
private static class UnscoredScoreDoc extends ScoreDoc {
public UnscoredScoreDoc(ScoreDoc scoreDoc) {
super(scoreDoc.doc, scoreDoc.score, scoreDoc.shardIndex);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof ScoreDoc sd) {
return Objects.equals(this.doc, sd.doc)
&& this.shardIndex == sd.shardIndex;
2022-02-11 21:08:23 +01:00
}
return false;
}
}
}