fix #2753 fix zero hit handling

This commit is contained in:
Shinsuke Sugaya 2023-06-29 16:49:17 +09:00
parent 47962a4938
commit 833449c65a
3 changed files with 272 additions and 7 deletions

View file

@ -180,7 +180,7 @@ public class RankFusionProcessor implements AutoCloseable {
final var docs = scoreDocMap.values().stream()
.sorted((e1, e2) -> Float.compare(toFloat(e2.get(scoreField)), toFloat(e1.get(scoreField)))).toList();
int offset = 0;
for (int i = 0; i < windowSize / 2; i++) {
for (int i = 0; i < windowSize / 2 && i < docs.size(); i++) {
if (!mainIdSet.contains(docs.get(i).get(idField))) {
offset++;
}
@ -193,9 +193,24 @@ public class RankFusionProcessor implements AutoCloseable {
if (Relation.EQUAL_TO.toString().equals(mainResult.getAllRecordCountRelation())) {
allRecordCount += offset;
}
return createResponseList(docs.subList(startPosition, startPosition + pageSize), allRecordCount,
mainResult.getAllRecordCountRelation(), mainResult.getQueryTime(), mainResult.isPartialResults(),
mainResult.getFacetResponse(), startPosition, pageSize, offset);
return createResponseList(extractList(docs, pageSize, startPosition), allRecordCount, mainResult.getAllRecordCountRelation(),
mainResult.getQueryTime(), mainResult.isPartialResults(), mainResult.getFacetResponse(), startPosition, pageSize, offset);
}
protected List<Map<String, Object>> extractList(final List<Map<String, Object>> docs, final int pageSize, final int startPosition) {
final int size = docs.size();
if (size == 0) {
return docs; // empty
}
int fromIndex = startPosition;
if (fromIndex >= size) {
fromIndex = size - 1;
}
int toIndex = startPosition + pageSize;
if (toIndex >= size) {
toIndex = size;
}
return docs.subList(fromIndex, toIndex);
}
protected List<Map<String, Object>> searchWithMainSearcher(final String query, final SearchRequestParams params,

View file

@ -69,6 +69,13 @@ public class SearchResult {
return new SearchResultBuilder();
}
@Override
public String toString() {
return "SearchResult [documentList=" + documentList + ", allRecordCount=" + allRecordCount + ", allRecordCountRelation="
+ allRecordCountRelation + ", queryTime=" + queryTime + ", partialResults=" + partialResults + ", facetResponse="
+ facetResponse + "]";
}
static class SearchResultBuilder {
private long allRecordCount;

View file

@ -95,7 +95,7 @@ public class RankFusionProcessorTest extends UnitFessTestCase {
}
}
public void test_1searcher10_1000docs_100size() throws Exception {
public void test_1searcher10_45_45_1000docs_100size() throws Exception {
String query = "*";
int allRecordCount = 1000;
int pageSize = 100;
@ -191,7 +191,7 @@ public class RankFusionProcessorTest extends UnitFessTestCase {
if (rankFusionProcessor.search(query, new TestSearchRequestParams(1000, pageSize, offset),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(offset, list.size());
assertEquals(allRecordCount + offset, list.getAllRecordCount());
assertEquals(11, list.getAllPageCount());
assertEquals(1045, list.getCurrentEndRecordNumber());
@ -208,6 +208,249 @@ public class RankFusionProcessorTest extends UnitFessTestCase {
}
}
public void test_1searcher0_0docs_100size() throws Exception {
String query = "*";
int allRecordCount = 0;
int pageSize = 100;
int offset = 0;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(0, list.size());
assertEquals(0, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(0, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(0, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher0_10docs_100size() throws Exception {
String query = "*";
int allRecordCount = 10;
int pageSize = 100;
int offset = 0;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(10, list.size());
assertEquals(10, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(10, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher0_1000docs_100size() throws Exception {
String query = "*";
int allRecordCount = 1000;
int pageSize = 100;
int offset = 0;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(1000, list.getAllRecordCount());
assertEquals(10, list.getAllPageCount());
assertEquals(100, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher10_0docs_100size() throws Exception {
String query = "*";
int allRecordCount = 0;
int pageSize = 100;
int offset = 10;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(10, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(10, list.size());
assertEquals(10, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(10, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher10_10docs_100size() throws Exception {
String query = "*";
int allRecordCount = 10;
int pageSize = 100;
int offset = 0;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(10, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(10, list.size());
assertEquals(10, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(10, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher10_1000docs_100size() throws Exception {
String query = "*";
int allRecordCount = 1000;
int pageSize = 100;
int offset = 0;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(10, 0, 0));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(1000, list.getAllRecordCount());
assertEquals(10, list.getAllPageCount());
assertEquals(100, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher1000_0docs_100size() throws Exception {
String query = "*";
int allRecordCount = 0;
int pageSize = 100;
int offset = 100;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 1000));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(100, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(100, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher1000_10docs_100size() throws Exception {
String query = "*";
int allRecordCount = 10;
int pageSize = 100;
int offset = 90;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 1000));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(100, list.getAllRecordCount());
assertEquals(1, list.getAllPageCount());
assertEquals(100, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
public void test_1searcher1000_1000docs_100size() throws Exception {
String query = "*";
int allRecordCount = 1000;
int pageSize = 100;
int offset = 50;
try (RankFusionProcessor rankFusionProcessor = new RankFusionProcessor()) {
rankFusionProcessor.setSeacher(new TestMainSearcher(allRecordCount));
rankFusionProcessor.register(new TestSubSearcher(0, 0, 1000));
rankFusionProcessor.init();
if (rankFusionProcessor.search(query, new TestSearchRequestParams(0, pageSize, 0),
OptionalThing.empty()) instanceof QueryResponseList list) {
assertEquals(pageSize, list.size());
assertEquals(1050, list.getAllRecordCount());
assertEquals(11, list.getAllPageCount());
assertEquals(100, list.getCurrentEndRecordNumber());
assertEquals(1, list.getCurrentPageNumber());
assertEquals(1, list.getCurrentStartRecordNumber());
assertEquals(offset, list.getOffset());
assertEquals(100, list.getPageSize());
assertEquals(0, list.getStart());
} else {
fail();
}
}
}
static class TestMainSearcher extends RankFusionSearcher {
private long allRecordCount;
@ -221,7 +464,7 @@ public class RankFusionProcessorTest extends UnitFessTestCase {
int start = params.getStartPosition();
int size = params.getPageSize();
SearchResultBuilder builder = SearchResult.create();
for (int i = start; i < start + size; i++) {
for (int i = start; i < start + size && i < allRecordCount; i++) {
Map<String, Object> doc = new HashMap<>();
doc.put(ID_FIELD, Integer.toString(i));
doc.put("score", 1.0f / (i + 1));