feat: add OpenSearch highlight snippets to search results
All checks were successful
CI / build (push) Successful in 1m23s
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Successful in 54s
CI / deploy (push) Successful in 39s
CI / deploy-feature (push) Has been skipped

- Add highlight field to ExecutionSummary record
- Request highlight fragments from OpenSearch when full-text search is active
- Pass matchContext to command palette for display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-25 09:29:07 +01:00
parent b32c97c02b
commit d9c8816647
3 changed files with 30 additions and 2 deletions

View File

@@ -125,6 +125,10 @@ public class OpenSearchIndex implements SearchIndex {
}
}
private static final List<String> HIGHLIGHT_FIELDS = List.of(
"error_message", "processors.input_body", "processors.output_body",
"processors.input_headers", "processors.output_headers");
private org.opensearch.client.opensearch.core.SearchRequest buildSearchRequest(
SearchRequest request, int size) {
return org.opensearch.client.opensearch.core.SearchRequest.of(b -> {
@@ -137,6 +141,17 @@ public class OpenSearchIndex implements SearchIndex {
.field(request.sortColumn())
.order("asc".equalsIgnoreCase(request.sortDir())
? SortOrder.Asc : SortOrder.Desc)));
// Add highlight when full-text search is active
if (request.text() != null && !request.text().isBlank()) {
b.highlight(h -> {
for (String field : HIGHLIGHT_FIELDS) {
h.fields(field, hf -> hf
.fragmentSize(120)
.numberOfFragments(1));
}
return h;
});
}
return b;
});
}
@@ -332,7 +347,18 @@ public class OpenSearchIndex implements SearchIndex {
src.get("duration_ms") != null ? ((Number) src.get("duration_ms")).longValue() : 0L,
(String) src.get("correlation_id"),
(String) src.get("error_message"),
null // diagramContentHash not stored in index
null, // diagramContentHash not stored in index
extractHighlight(hit)
);
}
private String extractHighlight(Hit<Map> hit) {
if (hit.highlight() == null || hit.highlight().isEmpty()) return null;
for (List<String> fragments : hit.highlight().values()) {
if (fragments != null && !fragments.isEmpty()) {
return fragments.get(0);
}
}
return null;
}
}