From 6d524cb4993a3530ae4e99378afb20e77a6bb528 Mon Sep 17 00:00:00 2001 From: tangwang Date: Thu, 4 Dec 2025 16:02:55 +0800 Subject: [PATCH] docs优化 --- docs/multi_select_faceting.md | 399 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- docs/搜索API对接指南.md | 23 +---------------------- frontend/index.html | 2 +- test_multi_select_facet.py | 288 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 4 files changed, 2 insertions(+), 710 deletions(-) delete mode 100644 docs/multi_select_faceting.md delete mode 100644 test_multi_select_facet.py diff --git a/docs/multi_select_faceting.md b/docs/multi_select_faceting.md deleted file mode 100644 index ea57de8..0000000 --- a/docs/multi_select_faceting.md +++ /dev/null @@ -1,399 +0,0 @@ -# Multi-Select Faceting 功能说明 - -## 概述 - -Multi-Select Faceting(多选分面)是业界标准的 Faceted Search 功能,允许用户在选中某个分面筛选项后,仍然能看到该分面的其他可选项,提供更好的探索式搜索体验。 - -## 功能特性 - -### 1. 两种 Faceting 模式 - -#### 标准模式(Conjunctive Faceting) -- **设置**: `multi_select: false`(默认) -- **行为**: 选中某个分面值后,该分面只显示选中的值 -- **适用场景**: 层级下钻、逐步精炼 -- **ES 实现**: 过滤器应用在 `query.bool.filter` - -#### Multi-Select 模式(Disjunctive Faceting) -- **设置**: `multi_select: true` -- **行为**: 选中某个分面值后,该分面仍显示所有可选项 -- **适用场景**: 颜色、品牌、尺码等可切换属性 -- **ES 实现**: 过滤器应用在 `post_filter` - -### 2. Selected 状态标记 - -所有 facet 值都包含 `selected` 字段,标记当前是否被选中: -- `selected: true` - 当前筛选项已被选中 -- `selected: false` - 当前筛选项未被选中 - -## 使用示例 - -### 示例 1: 标准 Category Faceting - -```json -{ - "query": "T恤", - "filters": { - "category1_name": "服装" - }, - "facets": [ - { - "field": "category1_name", - "size": 10, - "type": "terms", - "multi_select": false - } - ] -} -``` - -**响应**: -```json -{ - "results": [...], - "facets": [ - { - "field": "category1_name", - "values": [ - {"value": "服装", "count": 150, "selected": true} - ] - } - ] -} -``` - -### 示例 2: Multi-Select Brand Faceting - -```json -{ - "query": "手机", - "filters": { - "brand_name": "苹果" - }, - "facets": [ - { - "field": "brand_name", - "size": 10, - "type": "terms", - "multi_select": true - } - ] -} -``` - -**响应**: -```json -{ - "results": [...只包含苹果手机...], - "facets": [ - { - "field": "brand_name", - "values": [ - {"value": "苹果", "count": 150, "selected": true}, - {"value": "华为", "count": 120, "selected": false}, - {"value": "小米", "count": 98, "selected": false} - ] - } - ] -} -``` - -### 示例 3: Specifications Multi-Select - -```json -{ - "query": "衬衫", - "filters": { - "specifications": { - "name": "颜色", - "value": "白色" - } - }, - "facets": [ - { - "field": "specifications.颜色", - "size": 10, - "type": "terms", - "multi_select": true - }, - { - "field": "specifications.尺码", - "size": 10, - "type": "terms", - "multi_select": false - } - ] -} -``` - -**响应**: -```json -{ - "results": [...只包含白色衬衫...], - "facets": [ - { - "field": "specifications.颜色", - "label": "颜色", - "values": [ - {"value": "白色", "count": 50, "selected": true}, - {"value": "蓝色", "count": 35, "selected": false}, - {"value": "黑色", "count": 28, "selected": false} - ] - }, - { - "field": "specifications.尺码", - "label": "尺码", - "values": [ - {"value": "M", "count": 20, "selected": false}, - {"value": "L", "count": 18, "selected": false}, - {"value": "XL", "count": 12, "selected": false} - ] - } - ] -} -``` - -注意:尺码分面(`multi_select: false`)的统计是基于白色衬衫的。 - -### 示例 4: 混合多个 Multi-Select Facets - -```json -{ - "query": "*", - "filters": { - "category1_name": "玩具", - "specifications": [ - {"name": "颜色", "value": "红色"}, - {"name": "材质", "value": "塑料"} - ] - }, - "facets": [ - { - "field": "category1_name", - "size": 10, - "multi_select": true - }, - { - "field": "specifications.颜色", - "size": 10, - "multi_select": true - }, - { - "field": "specifications.材质", - "size": 10, - "multi_select": true - }, - { - "field": "specifications.年龄段", - "size": 10, - "multi_select": false - } - ] -} -``` - -**行为说明**: -- `category1_name`: 显示所有类目选项(玩具被标记为 selected) -- `specifications.颜色`: 显示所有颜色选项(红色被标记为 selected) -- `specifications.材质`: 显示所有材质选项(塑料被标记为 selected) -- `specifications.年龄段`: 只显示符合当前过滤条件的年龄段选项 - -## 前端集成建议 - -### React 示例 - -```jsx -function FacetComponent({ facet }) { - return ( -
-

{facet.label}

- {facet.values.map(value => ( - - ))} -
- ); -} -``` - -### Vue 示例 - -```vue - -``` - -## 技术实现细节 - -### Elasticsearch Query 结构 - -**Multi-Select Faceting** 使用 `post_filter` 实现: - -```json -{ - "query": { - "bool": { - "must": [...], - "filter": [ - // 只包含 multi_select=false 的过滤器 - {"term": {"category2_name": "短袖T恤"}} - ] - } - }, - "post_filter": { - "bool": { - "filter": [ - // 包含 multi_select=true 的过滤器 - {"term": {"brand_name": "苹果"}}, - { - "nested": { - "path": "specifications", - "query": { - "bool": { - "must": [ - {"term": {"specifications.name": "颜色"}}, - {"term": {"specifications.value": "白色"}} - ] - } - } - } - } - ] - } - }, - "aggs": { - // 所有聚合都基于 query 的结果(不受 post_filter 影响) - "brand_name_facet": {...}, - "specifications_颜色_facet": {...} - } -} -``` - -**关键点**: -- `query.bool.filter`: 影响结果和聚合 -- `post_filter`: 只影响结果,不影响聚合 -- 聚合统计基于 `query` 的结果,因此 multi-select facet 可以显示多个选项 - -## 最佳实践 - -### 1. 何时使用 Multi-Select - -| Facet 类型 | 推荐模式 | 原因 | -|-----------|---------|------| -| 颜色 | `multi_select: true` | 用户需要切换颜色 | -| 品牌 | `multi_select: true` | 用户需要比较不同品牌 | -| 尺码 | `multi_select: true` | 用户需要查看其他尺码 | -| 类目 | `multi_select: false` | 层级下钻 | -| 价格区间 | `multi_select: false` | 互斥选择 | -| 是否有货 | `multi_select: false` | 布尔值筛选 | - -### 2. 性能考虑 - -- **过多 Multi-Select**: 会增加 ES 查询复杂度 -- **建议**: 最多 3-5 个 multi-select facets -- **优化**: 对于不常用的属性使用标准模式 - -### 3. UI 设计建议 - -- **Multi-Select Facets**: 使用复选框(Checkbox) -- **Standard Facets**: 使用单选框(Radio)或链接 -- **Selected 状态**: 使用不同颜色或图标标识 - -## API 变更说明 - -### 新增字段 - -**FacetConfig**: -```json -{ - "field": "brand_name", - "size": 10, - "type": "terms", - "multi_select": true // 新增字段 -} -``` - -**FacetValue**: -```json -{ - "value": "苹果", - "count": 150, - "selected": true // 现在由后端返回真实状态 -} -``` - -### 兼容性 - -- `multi_select` 默认为 `false`,保持向后兼容 -- 旧版 API 调用仍然有效(使用标准模式) - -## 测试验证 - -运行测试脚本: -```bash -python test_multi_select_facet.py -``` - -测试覆盖: -1. ✓ 标准 Faceting (multi_select=false) -2. ✓ Multi-Select Faceting (multi_select=true) -3. ✓ Specifications Multi-Select -4. ✓ ES Query 结构验证 - -## 故障排查 - -### 问题 1: Multi-Select 不生效 - -**症状**: 设置了 `multi_select: true`,但仍然只返回一个值 - -**检查**: -1. 确认 `multi_select` 字段在请求中正确设置 -2. 检查 ES query 是否包含 `post_filter`(开启 `debug: true`) -3. 验证 Elasticsearch 版本支持 `post_filter` - -### 问题 2: Selected 标记不正确 - -**症状**: `selected` 字段没有正确标记 - -**检查**: -1. 确认 `filters` 中的字段名与 facet 字段名一致 -2. 对于 specifications,检查 `name` 和 `value` 是否匹配 -3. 检查 `filters` 的值类型(字符串、数组等) - -### 问题 3: 性能问题 - -**症状**: 启用 Multi-Select 后查询变慢 - -**优化**: -1. 减少 multi-select facets 数量 -2. 降低 facet `size` 参数 -3. 考虑使用缓存 -4. 为常用字段建立索引 - -## 参考资料 - -- [Elasticsearch Post Filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/filter-search-results.html#post-filter) -- [Algolia Disjunctive Faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#conjunctive-and-disjunctive-facets) -- [Amazon Product Search](https://www.amazon.com) - 业界最佳实践示例 - diff --git a/docs/搜索API对接指南.md b/docs/搜索API对接指南.md index a28df7e..6c42cab 100644 --- a/docs/搜索API对接指南.md +++ b/docs/搜索API对接指南.md @@ -318,38 +318,17 @@ curl -X POST "http://120.76.41.98:6002/search/" \ **重要特性**: `multi_select` 字段控制分面的行为模式。 + ##### 标准模式 (multi_select: false) - **行为**: 选中某个分面值后,该分面只显示选中的值 - **适用场景**: 层级类目、互斥选择 - **示例**: 类目下钻(玩具 > 娃娃 > 芭比) -```json -{ - "filters": {"category1_name": "玩具"}, - "facets": [ - {"field": "category1_name", "size": 10, "multi_select": false} - ] -} -``` -**响应**: 只返回 "玩具" 一个选项 - ##### Multi-Select 模式 (multi_select: true) ⭐ - **行为**: 选中某个分面值后,该分面仍显示所有可选项 - **适用场景**: 颜色、品牌、尺码等可切换属性 - **示例**: 选择了"红色"后,仍能看到"蓝色"、"绿色"等选项 -```json -{ - "filters": { - "specifications": {"name": "颜色", "value": "红色"} - }, - "facets": [ - {"field": "specifications.颜色", "size": 10, "multi_select": true} - ] -} -``` -**响应**: 返回所有颜色选项,"红色" 被标记为 `selected: true` - ##### 推荐配置 | 分面类型 | multi_select | 原因 | diff --git a/frontend/index.html b/frontend/index.html index 27001c6..81583f1 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -23,7 +23,7 @@