Kibana可视化能否实现自定义文本高亮?基于标注字符偏移场景
How to Highlight Pre-Annotated Text (With Character Offsets) in Kibana
Got it, let's break this down—you're working with Elasticsearch docs that have pre-defined annotations (like marking "dog" as ANIMAL with character offsets) and want to display those highlighted in Kibana, not just the standard search-term highlighting. Here are two solid approaches to make this work nicely:
1. Use Custom Script Fields in Discover (Great for Data Exploration)
If you want to see highlighted annotations while browsing your data in Discover, create a scripted field that builds HTML-formatted text with your highlights:
Step 1: Create the Scripted Field
- Go to Kibana Management > Index Patterns and select your target index.
- Navigate to the Scripted fields tab and click Add scripted field.
- Name it something like
highlighted_annotated_text, set the type to String. - Paste this Painless script (tweak styles and entity colors as needed):
String rawText = doc['text'].value; List annotations = doc['annotations'].value; // Sort annotations by start offset DESC to avoid breaking offsets when replacing annotations.sort((a, b) -> Integer.compare(b.start_offset, a.start_offset)); for (def annotation : annotations) { int start = annotation.start_offset; int end = annotation.end_offset; String highlightedSegment = switch(annotation.entity_type) { case "ANIMAL" -> "<span style='background-color: #ffeb3b; padding: 1px 3px; border-radius: 2px;'>" + rawText.substring(start, end) + "</span>"; case "PERSON" -> "<span style='background-color: #2196f3; color: white; padding: 1px 3px; border-radius: 2px;'>" + rawText.substring(start, end) + "</span>"; default -> rawText.substring(start, end); }; rawText = rawText.substring(0, start) + highlightedSegment + rawText.substring(end); } return rawText;
- Save the field.
Step 2: Enable HTML Rendering in Discover
- Go to Discover and add your new
highlighted_annotated_textfield to the table. - Click the field's menu icon (⋮) > Edit field format.
- Under Display, select HTML and save. Your annotated segments will now show up with custom colors!
2. Use Canvas for Dashboard Visualizations (Great for Shared Dashboards)
If you want to build a polished dashboard display, Kibana Canvas gives you more control over rendering. Here's how to set it up:
- Create a new Canvas workspace.
- Add a Text element to the canvas.
- Open the expression editor and paste this code (replace
your-indexwith your actual index name):
elasticsearch index="your-index" | map rows={ let rawText = row.text; let annotations = row.annotations; // Sort annotations in reverse order to prevent offset issues let sortedAnnotations = annotations | sort by start_offset desc; let highlightedText = sortedAnnotations | reduce initial=rawText fn=(acc, ann) => { let preText = substring(acc, 0, ann.start_offset); let entityText = substring(acc, ann.start_offset, ann.end_offset); let postText = substring(acc, ann.end_offset); // Apply styling based on entity type let styledEntity = switch ann.entity_type { case "ANIMAL" -> strcat('<span style="background: #ffeb3b; padding: 2px 4px; border-radius: 3px;">', entityText, '</span>'); case "PERSON" -> strcat('<span style="background: #2196f3; color: white; padding: 2px 4px; border-radius: 3px;">', entityText, '</span>'); default -> entityText; }; return strcat(preText, styledEntity, postText); }; return objectSet(row, "highlighted_text", highlightedText); } | render as=html
- Adjust the styling (colors, padding, border-radius) to match your dashboard's look. You can also add filters or other Canvas elements to refine the display.
Key Notes to Avoid Headaches
- Double-check your offsets: Make sure the start/end offsets stored in Elasticsearch are character-based (not byte-based)—UTF-8 characters can take multiple bytes, which will break your highlighting if offsets don't match.
- Sort annotations in reverse: By sorting annotations from highest start offset to lowest, you prevent earlier replacements from shifting the positions of later segments.
- Customize styles freely: Tweak the CSS in the
<span>tags to match your brand or make different entity types instantly distinguishable.
内容的提问来源于stack exchange,提问作者W.P. McNeill
相关产品推荐
相关产品推荐

