启东 网站开发企业为什么要增资
2026/1/13 21:53:52 网站建设 项目流程
启东 网站开发,企业为什么要增资,wordpress 手动缩略图,展览公司网站模板从零构建高效搜索#xff1a;Elasticsearch分页与高亮实战指南你有没有遇到过这样的场景#xff1f;用户在搜索框输入“Java并发编程”#xff0c;点击回车后#xff0c;页面卡顿两秒才返回结果#xff0c;翻到第50页时直接报错“请求超时”#xff1b;更糟的是#xff…从零构建高效搜索Elasticsearch分页与高亮实战指南你有没有遇到过这样的场景用户在搜索框输入“Java并发编程”点击回车后页面卡顿两秒才返回结果翻到第50页时直接报错“请求超时”更糟的是匹配的关键词根本没有高亮用户得一个字一个字地扫视内容。这背后的问题往往不是数据量太大而是我们对Elasticsearch基本用法的理解还停留在表面。尤其是分页查询和高亮显示这两个看似简单的功能一旦用错轻则体验拉胯重则压垮集群。今天我们就来拆解这两个核心能力——不讲理论堆砌只聚焦真实项目中怎么用、怎么避坑、怎么优化。分页不止是from size深分页陷阱你踩过几个别再无脑写from1000, size10了新手上手 Elasticsearch 最常写的代码是什么{ from: 1000, size: 10, query: { ... } }看起来没问题跳过前1000条取第1001~1010条。但你知道吗这个请求在分布式环境下其实是这样执行的假设你的索引有5个分片。协调节点会向每个分片发送请求“请返回你本地排序后的第1001~1010条”。可每个分片并不知道全局排名所以它只能先把前1010条都查出来排序后截取再发给协调节点。最后协调节点再做一次合并排序取出真正的第1001~1010条。也就是说为了拿10条数据系统实际处理了5 × 1010 5050条记录。随着from越来越大内存和CPU消耗呈线性增长。当from size 10000时默认就会触发熔断Result window is too large, from size must be less than or equal to: [10000]你可以调大index.max_result_window但这是饮鸩止渴——堆内存爆炸只是时间问题。真正适合深分页的方案search_after如果你需要遍历成千上万条数据比如后台导出、日志审计应该用search_after。它的思路很像数据库里的游标记住上一页最后一个文档的排序值下次直接从那个位置往后读。它是怎么工作的假设你要按发布时间倒序展示文章每页10条第一次请求不需要游标{ size: 10, query: { match: { title: elasticsearch基本用法 } }, sort: [ { publish_date: desc }, { _id: asc } // 必须加唯一字段防歧义 ] }拿到第一页最后一条数据{ publish_date: 2023-06-01T08:00:00, _id: article_9876 }第二页就用这两个值作为“起点”{ size: 10, query: { ... }, sort: [ ... ], search_after: [2023-06-01T08:00:00, article_9876] }注意sort字段必须包含唯一组合如时间ID否则可能出现漏数据或重复。为什么它性能稳定因为每次请求只扫描一页的数据量不会随翻页深度增加而变慢。各分片只需定位到指定排序值之后的下N条即可无需生成大量中间结果。Java 实现示例基于官方 High Level Clientpublic SearchResponse fetchNextPage(RestHighLevelClient client, String lastDate, String lastId) throws IOException { SearchRequest request new SearchRequest(articles); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.matchQuery(content, elasticsearch基本用法)); sourceBuilder.size(10); sourceBuilder.sort(publish_date, SortOrder.DESC); sourceBuilder.sort(_id, SortOrder.ASC); if (lastDate ! null lastId ! null) { sourceBuilder.searchAfter(Arrays.asList(lastDate, lastId)); } request.source(sourceBuilder); return client.search(request, RequestOptions.DEFAULT); }关键点- 维护前后请求之间的sort值传递- 前端需缓存游标状态可用 Base64 编码传输- 不支持“跳转任意页”仅适用于连续翻页✅ 推荐使用场景后台管理列表、大数据导出、离线分析任务。高亮不只是em包一下准确性和性能一样都不能妥协用户为什么看不到关键词高亮很多开发者以为加上highlight就万事大吉highlight: { fields: { content: {} } }结果发现- 中文断词不准“搜索引擎”被拆成“搜”“索”“引”“擎”- 返回的片段太长整段文字都被标黄- 查询速度明显下降QPS 从 1000 掉到 300这些问题根源在于你没告诉 Elasticsearch 如何高效又精准地找匹配文本。高亮的本质一次独立于主查询的文本分析过程很多人误以为高亮是从_source里直接替换字符串。其实不然。Elasticsearch 会在匹配字段中重新运行一次轻量级分析流程找出最相关的文本片段并插入标签。这个过程发生在协调节点非常吃 CPU。而且默认使用的plain highlighter是基于标准分词器的对中文支持极差。如何让高亮又快又准第一步选对高亮器类型类型适用场景性能准确性plain默认通用短文本一般低fvh(Fast Vector Highlighter)长文本、强调速度⭐⭐⭐⭐⭐⭐⭐⭐postings精确短字段匹配⭐⭐⭐⭐⭐⭐推荐优先使用fvh但它要求字段开启 term vector 存储PUT /articles { mappings: { properties: { content: { type: text, term_vector: with_positions_offsets // 关键配置 } } } }开启后高亮性能可提升数倍且支持精确到字符级别的定位。第二步合理控制摘要长度避免返回整个字段内容设置合理的片段参数highlight: { pre_tags: [mark], post_tags: [/mark], fields: { title: { fragment_size: 150, number_of_fragments: 1 }, content: { type: fvh, fragment_size: 180, number_of_fragments: 3, no_match_size: 100 // 没匹配时也返回前100字符 } } }解释一下这几个参数的实际意义-fragment_size: 每个片段最多多少字符不是字数中文要注意-number_of_fragments: 返回几个高亮块0 表示返回完整字段-no_match_size: 即使没找到关键词也返回一段摘要提升用户体验第三步Spring Data Elasticsearch 实战代码Service public class ArticleSearchService { Autowired private ElasticsearchTemplate elasticsearchTemplate; public ListSearchResult searchWithHighlight(String keyword) { NativeSearchQueryBuilder queryBuilder new NativeSearchQueryBuilder(); // 主查询 queryBuilder.withQuery(QueryBuilders.matchQuery(content, keyword)); // 高亮配置 HighlightBuilder highlightBuilder new HighlightBuilder() .field(title, 150, 1) .field(content, 180, 3) .preTags(mark) .postTags(/mark) .highlighterType(fvh); // 使用 fvh queryBuilder.withHighlightBuilder(highlightBuilder); SearchHitsArticle hits elasticsearchTemplate.search( queryBuilder.build(), Article.class); return hits.stream().map(hit - { SearchResult result new SearchResult(); result.setId(hit.getId()); result.setTitle(hit.getContent().getTitle()); result.setContent(hit.getContent().getContent()); // 提取高亮片段 ListString titleHls hit.getHighlightField(title); ListString contentHls hit.getHighlightField(content); result.setHighlightedTitle(titleHls.isEmpty() ? null : titleHls.get(0)); result.setHighlightedContent(contentHls.isEmpty() ? null : contentHls.get(0)); return result; }).collect(Collectors.toList()); } }前端可以直接渲染highlightedTitle字段记得做好 XSS 防护真实业务场景怎么落地场景一电商平台商品搜索需求用户搜“无线蓝牙耳机”希望看到标题和描述中关键词高亮支持翻几十页。挑战- 商品总量百万级传统from/size翻到第50页直接卡死- 描述字段含HTML标签高亮可能破坏结构解决方案1. 分页改用search_after排序规则销量降序 上架时间降序 ID 升序2. 对description字段启用fvh高亮设置fragment_size2003. 前端维护双向游标前进/后退通过 JWT 或 sessionStorage 缓存上下文4. 对富文本字段先 strip HTML 再高亮防止标签错乱场景二企业知识库检索需求员工查“elasticsearch基本用法”文档正文要高亮。痛点- 文档包含代码块for(int i0;...被错误标亮- 搜索结果太多用户找不到重点对策1. 使用matched_fields只对非代码区域高亮2. 设置require_field_match: true避免无关字段也被渲染3. 结合前端虚拟滚动在可视区域内动态注入高亮标签4. 对技术术语建立同义词库提高召回率设计时必须考虑的四个维度1. 性能权衡别为美观牺牲响应速度高亮和分页都会显著增加查询耗时。建议策略- 首页/高频访问页开启全量高亮- 深层页面仅标题高亮或关闭高亮- API 接口提供highlightfalse参数供客户端控制2. 安全防护别让mark成为 XSS 入口返回的高亮字段是带 HTML 标签的字符串前端必须- Vue 使用v-html时配合DOMPurify清洗- React 用dangerouslySetInnerHTML前进行 escape 处理- 后端也可预处理替换为 CSS class由前端统一渲染样式3. 中文适配IK 分词器是标配默认分词器对中文极其不友好。务必安装 IK 插件./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.0/elasticsearch-analysis-ik-7.10.0.zip并在 mapping 中指定analyzer: ik_max_word这样才能保证“全文检索”不会被切成“全”“文”“检”“索”。4. 监控可观测性让问题提前暴露在生产环境埋点监控以下指标- 平均查询延迟含/不含高亮-search_after请求占比- 高亮字段数量分布- termvector 存储占用增长率一旦发现某类查询延迟突增立即检查是否开启了过多字段高亮。掌握这些elasticsearch基本用法你不只是会写 DSL而是真正理解了如何在性能、一致性与用户体验之间找到平衡点。分页不是简单跳页高亮也不只是视觉装饰。它们是搜索系统能否扛住流量、留住用户的关键细节。下一步不妨试试把这些技巧应用到你的项目中——比如把老系统的from/size改造成search_after看看接口延迟能降多少或者给知识库加上精准中文高亮看用户停留时长有没有提升如果你在实现过程中遇到了其他挑战欢迎在评论区分享讨论。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询