feat: add OpenSearch highlight snippets to search results
- 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:
@@ -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(
|
private org.opensearch.client.opensearch.core.SearchRequest buildSearchRequest(
|
||||||
SearchRequest request, int size) {
|
SearchRequest request, int size) {
|
||||||
return org.opensearch.client.opensearch.core.SearchRequest.of(b -> {
|
return org.opensearch.client.opensearch.core.SearchRequest.of(b -> {
|
||||||
@@ -137,6 +141,17 @@ public class OpenSearchIndex implements SearchIndex {
|
|||||||
.field(request.sortColumn())
|
.field(request.sortColumn())
|
||||||
.order("asc".equalsIgnoreCase(request.sortDir())
|
.order("asc".equalsIgnoreCase(request.sortDir())
|
||||||
? SortOrder.Asc : SortOrder.Desc)));
|
? 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;
|
return b;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -332,7 +347,18 @@ public class OpenSearchIndex implements SearchIndex {
|
|||||||
src.get("duration_ms") != null ? ((Number) src.get("duration_ms")).longValue() : 0L,
|
src.get("duration_ms") != null ? ((Number) src.get("duration_ms")).longValue() : 0L,
|
||||||
(String) src.get("correlation_id"),
|
(String) src.get("correlation_id"),
|
||||||
(String) src.get("error_message"),
|
(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public record ExecutionSummary(
|
|||||||
long durationMs,
|
long durationMs,
|
||||||
String correlationId,
|
String correlationId,
|
||||||
String errorMessage,
|
String errorMessage,
|
||||||
String diagramContentHash
|
String diagramContentHash,
|
||||||
|
String highlight
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ function LayoutContent() {
|
|||||||
meta: `${e.routeId} · ${e.applicationName ?? ''} · ${formatDuration(e.durationMs)}`,
|
meta: `${e.routeId} · ${e.applicationName ?? ''} · ${formatDuration(e.durationMs)}`,
|
||||||
path: `/exchanges/${e.executionId}`,
|
path: `/exchanges/${e.executionId}`,
|
||||||
serverFiltered: true,
|
serverFiltered: true,
|
||||||
|
matchContext: e.highlight ?? undefined,
|
||||||
}));
|
}));
|
||||||
return [...catalogData, ...exchangeItems];
|
return [...catalogData, ...exchangeItems];
|
||||||
}, [catalogData, exchangeResults]);
|
}, [catalogData, exchangeResults]);
|
||||||
|
|||||||
Reference in New Issue
Block a user