如何在Hibernate Search 6中获取结果集的高亮匹配字段?
Hibernate Search 6 实现搜索结果匹配字段提取与前端高亮
1. 开启查询的命中详情与高亮支持
在构建搜索查询时,需显式开启命中详情获取,并配置高亮规则,指定要追踪的字段:
List<SearchResultDto> results = searchSession.search(YourEntity.class) .where(f -> f.match() .fields("name", "description", "id") .matching("test") .fuzzy()) // 你的模糊搜索逻辑 .fetchHitDetails() // 启用命中详情获取 .highlighting(h -> h .fields("name", "description", "id") // 指定需要高亮的字段 .options(o -> o .preTags("<span class='highlight'>") // 自定义高亮前缀标签 .postTags("</span>") // 自定义高亮后缀标签 .fragmentSize(100) // 高亮片段长度 .numberOfFragments(1))) // 返回的片段数量 .projection(f -> f.composite( f.entity(), // 获取原始实体 f.hit().matchedFields(), // 获取所有匹配的字段名称集合 f.highlight("name"), // 获取name字段的高亮片段 f.highlight("description"), // 获取description字段的高亮片段 f.highlight("id") // 获取id字段的高亮片段 )) .fetch(10) // 分页参数,对应你需要的10条结果 .map(projection -> { YourEntity entity = projection.get(0); Set<String> matchedFields = projection.get(1); List<String> nameHighlights = projection.get(2); List<String> descriptionHighlights = projection.get(3); List<String> idHighlights = projection.get(4); // 封装为前端需要的DTO SearchResultDto dto = new SearchResultDto(); dto.setId(entity.getId()); dto.setName(entity.getName()); dto.setDescription(entity.getDescription()); dto.setMatchedFields(new ArrayList<>(matchedFields)); // 转成List方便前端处理 // 处理高亮片段,无匹配时返回null dto.setHighlightedName(nameHighlights.isEmpty() ? null : nameHighlights.get(0)); dto.setHighlightedDescription(descriptionHighlights.isEmpty() ? null : descriptionHighlights.get(0)); dto.setHighlightedId(idHighlights.isEmpty() ? null : idHighlights.get(0)); return dto; }) .toList();
2. 定义前端接收的DTO
创建包含原始字段、匹配字段列表、高亮片段的传输对象:
public class SearchResultDto { private String id; private String name; private String description; private List<String> matchedFields; // 存储触发匹配的字段名,如["name", "description"] private String highlightedName; // 带高亮标记的name内容 private String highlightedDescription; // 带高亮标记的description内容 private String highlightedId; // 带高亮标记的id内容 // getter、setter 省略 }
3. Angular 前端高亮渲染
前端拿到DTO后,直接渲染带标记的高亮字段即可,同时可通过matchedFields展示匹配原因:
- 添加高亮样式:
.highlight { background-color: #ffeb3b; font-weight: 500; }
- 组件模板示例:
<div *ngFor="let item of searchResults"> <p>匹配字段:{{ item.matchedFields.join(', ') }}</p> <p>名称:<span [innerHTML]="item.highlightedName || item.name"></span></p> <p>描述:<span [innerHTML]="item.highlightedDescription || item.description"></span></p> <p>ID:<span [innerHTML]="item.highlightedId || item.id"></span></p> </div>
注意:使用[innerHTML]才能解析HTML高亮标签,若担心XSS风险,可提前在后端对内容做转义处理。
内容的提问来源于stack exchange,提问作者Gadreel
相关产品推荐
相关产品推荐

