Skip to content

Commit 25f70bb

Browse files
committed
Revert "Rescore collapsed documents (#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 #27243
1 parent 96b7c03 commit 25f70bb

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

+22
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

+3
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

+6-13
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

-66
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)