Skip to content

Commit b9f277e

Browse files
authored
Fix minimized_round_trips in lookup runtime fields (#107785) (#107801)
Today, we have disabled ccs_minimized_round_trips for lookup requests, under the assumption that cross-cluster lookups occur when ccs_minimized_round_trips is disabled in the main search request. However, this assumption does not hold true for cases where the search is local but the lookup happens remotely.
1 parent b5b26b2 commit b9f277e

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

docs/changelog/107785.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 107785
2+
summary: Fix `minimized_round_trips` in lookup runtime fields
3+
area: Search
4+
type: bug
5+
issues: []

server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CrossClusterIT.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.test.InternalTestCluster;
5151
import org.elasticsearch.test.NodeRoles;
5252
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
53+
import org.elasticsearch.test.transport.MockTransportService;
5354
import org.elasticsearch.transport.TransportActionProxy;
5455
import org.elasticsearch.transport.TransportService;
5556
import org.elasticsearch.xcontent.XContentParser;
@@ -62,6 +63,7 @@
6263
import java.util.Map;
6364
import java.util.concurrent.CountDownLatch;
6465
import java.util.concurrent.TimeUnit;
66+
import java.util.concurrent.atomic.AtomicInteger;
6567
import java.util.concurrent.atomic.AtomicReference;
6668
import java.util.stream.Collectors;
6769

@@ -446,6 +448,64 @@ public void testLookupFields() throws Exception {
446448
assertThat(hit2.field("to").getValues(), contains(Map.of("name", List.of("Local B")), Map.of("name", List.of("Local C"))));
447449
});
448450
}
451+
// Search locally, but lookup fields on remote clusters
452+
{
453+
final String remoteLookupFields = """
454+
{
455+
"from": {
456+
"type": "lookup",
457+
"target_index": "cluster_a:users",
458+
"input_field": "from_user",
459+
"target_field": "_id",
460+
"fetch_fields": ["name"]
461+
},
462+
"to": {
463+
"type": "lookup",
464+
"target_index": "cluster_a:users",
465+
"input_field": "to_user",
466+
"target_field": "_id",
467+
"fetch_fields": ["name"]
468+
}
469+
}
470+
""";
471+
final Map<String, Object> remoteRuntimeMappings;
472+
try (XContentParser parser = createParser(JsonXContent.jsonXContent, remoteLookupFields)) {
473+
remoteRuntimeMappings = parser.map();
474+
}
475+
AtomicInteger searchSearchRequests = new AtomicInteger(0);
476+
for (TransportService ts : cluster("cluster_a").getInstances(TransportService.class)) {
477+
MockTransportService transportService = (MockTransportService) ts;
478+
transportService.addRequestHandlingBehavior(TransportSearchShardsAction.NAME, (handler, request, channel, task) -> {
479+
handler.messageReceived(request, channel, task);
480+
searchSearchRequests.incrementAndGet();
481+
});
482+
}
483+
for (boolean ccsMinimizeRoundtrips : List.of(true, false)) {
484+
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(new TermQueryBuilder("to_user", "c"))
485+
.runtimeMappings(remoteRuntimeMappings)
486+
.sort(new FieldSortBuilder("duration"))
487+
.fetchField("from")
488+
.fetchField("to");
489+
SearchRequest request = new SearchRequest("local_calls").source(searchSourceBuilder);
490+
request.setCcsMinimizeRoundtrips(ccsMinimizeRoundtrips);
491+
assertResponse(client().search(request), response -> {
492+
assertHitCount(response, 1);
493+
SearchHit hit = response.getHits().getHits()[0];
494+
assertThat(hit.getIndex(), equalTo("local_calls"));
495+
assertThat(hit.field("from").getValues(), contains(Map.of("name", List.of("Remote A"))));
496+
assertThat(
497+
hit.field("to").getValues(),
498+
contains(Map.of("name", List.of("Remote B")), Map.of("name", List.of("Remote C")))
499+
);
500+
});
501+
if (ccsMinimizeRoundtrips) {
502+
assertThat(searchSearchRequests.get(), equalTo(0));
503+
} else {
504+
assertThat(searchSearchRequests.get(), greaterThan(0));
505+
searchSearchRequests.set(0);
506+
}
507+
}
508+
}
449509
}
450510

451511
@Override

server/src/main/java/org/elasticsearch/action/search/FetchLookupFieldsPhase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void run() {
8383
: "lookup across clusters only if [ccs_minimize_roundtrips] is disabled";
8484
for (LookupField lookupField : cluster.lookupFields) {
8585
final SearchRequest searchRequest = lookupField.toSearchRequest(clusterAlias);
86-
searchRequest.setCcsMinimizeRoundtrips(false);
86+
searchRequest.setCcsMinimizeRoundtrips(context.getRequest().isCcsMinimizeRoundtrips());
8787
multiSearchRequest.add(searchRequest);
8888
}
8989
}

0 commit comments

Comments
 (0)