Skip to content

Commit a0e7934

Browse files
committed
Revert "Rescore collapsed documents (elastic#28521)"
This reverts commit f057fc2. The rescorer does not resort the collapsed values inside the top docs during rescoring. For this reason the Lucene rescorer is not compatible with collapsing. Relates elastic#27243
1 parent cf2d7f7 commit a0e7934

File tree

4 files changed

+31
-79
lines changed

4 files changed

+31
-79
lines changed

rest-api-spec/src/main/resources/rest-api-spec/test/search/110_field_collapsing.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,28 @@ setup:
237237
search_after: [6]
238238
sort: [{ sort: desc }]
239239

240+
---
241+
"field collapsing and rescore":
242+
243+
- skip:
244+
version: " - 5.2.99"
245+
reason: this uses a new API that has been added in 5.3
246+
247+
- do:
248+
catch: /cannot use \`collapse\` in conjunction with \`rescore\`/
249+
search:
250+
index: test
251+
type: test
252+
body:
253+
collapse: { field: numeric_group }
254+
rescore:
255+
window_size: 20
256+
query:
257+
rescore_query:
258+
match_all: {}
259+
query_weight: 1
260+
rescore_query_weight: 2
261+
240262
---
241263
"no hits and inner_hits":
242264

server/src/main/java/org/elasticsearch/search/collapse/CollapseBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ public CollapseContext build(SearchContext context) {
225225
if (context.searchAfter() != null) {
226226
throw new SearchContextException(context, "cannot use `collapse` in conjunction with `search_after`");
227227
}
228+
if (context.rescore() != null && context.rescore().isEmpty() == false) {
229+
throw new SearchContextException(context, "cannot use `collapse` in conjunction with `rescore`");
230+
}
228231

229232
MappedFieldType fieldType = context.getQueryShardContext().fieldMapper(field);
230233
if (fieldType == null) {

server/src/main/java/org/elasticsearch/search/query/TopDocsCollectorContext.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ void postProcess(QuerySearchResult result) {
128128
static class CollapsingTopDocsCollectorContext extends TopDocsCollectorContext {
129129
private final DocValueFormat[] sortFmt;
130130
private final CollapsingTopDocsCollector<?> topDocsCollector;
131-
private final boolean rescore;
132131

133132
/**
134133
* Ctr
@@ -140,14 +139,13 @@ static class CollapsingTopDocsCollectorContext extends TopDocsCollectorContext {
140139
private CollapsingTopDocsCollectorContext(CollapseContext collapseContext,
141140
@Nullable SortAndFormats sortAndFormats,
142141
int numHits,
143-
boolean trackMaxScore, boolean rescore) {
142+
boolean trackMaxScore) {
144143
super(REASON_SEARCH_TOP_HITS, numHits);
145144
assert numHits > 0;
146145
assert collapseContext != null;
147146
Sort sort = sortAndFormats == null ? Sort.RELEVANCE : sortAndFormats.sort;
148147
this.sortFmt = sortAndFormats == null ? new DocValueFormat[] { DocValueFormat.RAW } : sortAndFormats.formats;
149148
this.topDocsCollector = collapseContext.createTopDocs(sort, numHits, trackMaxScore);
150-
this.rescore = rescore;
151149
}
152150

153151
@Override
@@ -160,11 +158,6 @@ Collector create(Collector in) throws IOException {
160158
void postProcess(QuerySearchResult result) throws IOException {
161159
result.topDocs(topDocsCollector.getTopDocs(), sortFmt);
162160
}
163-
164-
@Override
165-
boolean shouldRescore() {
166-
return rescore;
167-
}
168161
}
169162

170163
abstract static class SimpleTopDocsCollectorContext extends TopDocsCollectorContext {
@@ -339,6 +332,11 @@ static TopDocsCollectorContext createTopDocsCollectorContext(SearchContext searc
339332
return new ScrollingTopDocsCollectorContext(reader, query, searchContext.scrollContext(),
340333
searchContext.sort(), numDocs, searchContext.trackScores(), searchContext.numberOfShards(),
341334
searchContext.trackTotalHits(), hasFilterCollector);
335+
} else if (searchContext.collapse() != null) {
336+
boolean trackScores = searchContext.sort() == null ? true : searchContext.trackScores();
337+
int numDocs = Math.min(searchContext.from() + searchContext.size(), totalNumDocs);
338+
return new CollapsingTopDocsCollectorContext(searchContext.collapse(),
339+
searchContext.sort(), numDocs, trackScores);
342340
} else {
343341
int numDocs = Math.min(searchContext.from() + searchContext.size(), totalNumDocs);
344342
final boolean rescore = searchContext.rescore().isEmpty() == false;
@@ -348,11 +346,6 @@ static TopDocsCollectorContext createTopDocsCollectorContext(SearchContext searc
348346
numDocs = Math.max(numDocs, rescoreContext.getWindowSize());
349347
}
350348
}
351-
if (searchContext.collapse() != null) {
352-
boolean trackScores = searchContext.sort() == null ? true : searchContext.trackScores();
353-
return new CollapsingTopDocsCollectorContext(searchContext.collapse(),
354-
searchContext.sort(), numDocs, trackScores, rescore);
355-
}
356349
return new SimpleTopDocsCollectorContext(reader, query, searchContext.sort(), searchContext.searchAfter(), numDocs,
357350
searchContext.trackScores(), searchContext.trackTotalHits(), hasFilterCollector) {
358351
@Override

server/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,13 @@
3636
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
3737
import org.elasticsearch.search.SearchHit;
3838
import org.elasticsearch.search.SearchHits;
39-
import org.elasticsearch.search.collapse.CollapseBuilder;
4039
import org.elasticsearch.search.rescore.QueryRescoreMode;
4140
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
4241
import org.elasticsearch.search.sort.SortBuilders;
4342
import org.elasticsearch.test.ESIntegTestCase;
4443

45-
import java.io.IOException;
4644
import java.util.Arrays;
4745
import java.util.Comparator;
48-
import java.util.Map;
49-
import java.util.stream.Collectors;
5046

5147
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
5248
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
@@ -71,7 +67,6 @@
7167
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThirdHit;
7268
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
7369
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasScore;
74-
import static org.hamcrest.Matchers.containsInAnyOrder;
7570
import static org.hamcrest.Matchers.containsString;
7671
import static org.hamcrest.Matchers.equalTo;
7772
import static org.hamcrest.Matchers.greaterThan;
@@ -753,65 +748,4 @@ public void testRescorePhaseWithInvalidSort() throws Exception {
753748
assertThat(hit.getScore(), equalTo(101f));
754749
}
755750
}
756-
757-
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/28932")
758-
public void testRescoreAfterCollapse() throws Exception {
759-
assertAcked(prepareCreate("test")
760-
.addMapping(
761-
"type1",
762-
jsonBuilder()
763-
.startObject()
764-
.startObject("properties")
765-
.startObject("group")
766-
.field("type", "keyword")
767-
.endObject()
768-
.endObject()
769-
.endObject())
770-
);
771-
772-
ensureGreen("test");
773-
774-
indexDocument(1, "miss", "a", 1, 10);
775-
indexDocument(2, "name", "a", 2, 20);
776-
indexDocument(3, "name", "b", 2, 30);
777-
// should be highest on rescore, but filtered out during collapse
778-
indexDocument(4, "name", "b", 1, 40);
779-
780-
refresh("test");
781-
782-
SearchResponse searchResponse = client().prepareSearch("test")
783-
.setTypes("type1")
784-
.setQuery(staticScoreQuery("static_score"))
785-
.addRescorer(new QueryRescorerBuilder(staticScoreQuery("static_rescore")))
786-
.setCollapse(new CollapseBuilder("group"))
787-
.get();
788-
789-
assertThat(searchResponse.getHits().totalHits, equalTo(3L));
790-
assertThat(searchResponse.getHits().getHits().length, equalTo(2));
791-
792-
Map<String, Float> collapsedHits = Arrays
793-
.stream(searchResponse.getHits().getHits())
794-
.collect(Collectors.toMap(SearchHit::getId, SearchHit::getScore));
795-
796-
assertThat(collapsedHits.keySet(), containsInAnyOrder("2", "3"));
797-
assertThat(collapsedHits.get("2"), equalTo(22F));
798-
assertThat(collapsedHits.get("3"), equalTo(32F));
799-
}
800-
801-
private QueryBuilder staticScoreQuery(String scoreField) {
802-
return functionScoreQuery(termQuery("name", "name"), ScoreFunctionBuilders.fieldValueFactorFunction(scoreField))
803-
.boostMode(CombineFunction.REPLACE);
804-
}
805-
806-
private void indexDocument(int id, String name, String group, int score, int rescore) throws IOException {
807-
XContentBuilder docBuilder =jsonBuilder()
808-
.startObject()
809-
.field("name", name)
810-
.field("group", group)
811-
.field("static_score", score)
812-
.field("static_rescore", rescore)
813-
.endObject();
814-
815-
client().prepareIndex("test", "type1", Integer.toString(id)).setSource(docBuilder).get();
816-
}
817751
}

0 commit comments

Comments
 (0)