排名与相关性 #

排名机制概述 #

Algolia使用多维度排名算法来确定搜索结果的顺序,确保最相关的结果排在前面。

排名公式 #

text
排名 = typo + geo + words + filters + proximity + attribute + exact + custom

每个维度独立计算分数,按顺序比较。

排名维度详解 #

1. Typo(拼写容错) #

衡量匹配的拼写准确度:

text
查询: "iphone"
记录: "iPhone" → 0个拼写错误 → 最高分
记录: "iphne"  → 1个拼写错误 → 次高分
记录: "iphon"  → 1个拼写错误 → 次高分
拼写错误数 排名
0个错误 最高
1个错误 次高
2个错误 较低

2. Geo(地理位置) #

按距离排序(仅当使用地理搜索时):

javascript
index.search('store', {
  aroundLatLng: '37.7749,-122.4194'
});

// 结果按距离排序
// 距离越近,排名越高

3. Words(词匹配) #

衡量查询词的匹配程度:

text
查询: "iphone pro"
记录: "iPhone Pro" → 匹配2个词 → 最高分
记录: "iPhone"     → 匹配1个词 → 次高分
记录: "Pro Phone"  → 匹配1个词 → 次高分
匹配词数 排名
全部匹配 最高
部分匹配 较低

4. Filters(过滤器匹配) #

衡量过滤条件的匹配程度:

javascript
// 使用可选过滤时生效
filters: 'brand:Apple'
optionalFilters: 'category:Phones'

5. Proximity(接近度) #

衡量匹配词之间的距离:

text
查询: "phone case"
记录: "phone case"        → 距离0 → 最高分
记录: "phone protective case" → 距离1 → 次高分
记录: "case for phone"    → 距离2 → 较低分

6. Attribute(属性优先级) #

根据匹配的属性优先级排名:

javascript
searchableAttributes: [
  'name',         // 最高优先级
  'brand',        // 中等优先级
  'description'   // 较低优先级
]

// 查询: "apple"
// 匹配name → 最高分
// 匹配brand → 中等分
// 匹配description → 较低分

7. Exact(精确匹配) #

衡量匹配的精确程度:

text
查询: "iphone"
记录: "iPhone"      → 精确匹配 → 最高分
记录: "iPhone 15"   → 前缀匹配 → 次高分
记录: "my iPhone"   → 包含匹配 → 较低分

8. Custom(自定义排名) #

用户自定义的排名规则:

javascript
customRanking: [
  'desc(rating)',      // 评分高的排前面
  'desc(popularity)',  // 人气高的排前面
  'asc(price)'         // 价格低的排前面
]

排名计算示例 #

示例数据 #

json
[
  {
    "objectID": "1",
    "name": "iPhone 15 Pro",
    "brand": "Apple",
    "rating": 4.8,
    "popularity": 9000
  },
  {
    "objectID": "2",
    "name": "iPhone 15",
    "brand": "Apple",
    "rating": 4.7,
    "popularity": 8500
  },
  {
    "objectID": "3",
    "name": "iPhone Case",
    "brand": "Apple",
    "rating": 4.5,
    "popularity": 5000
  }
]

查询 “iphone pro” #

排名过程:

text
记录1: "iPhone 15 Pro"
├── typo: 0 (无拼写错误)
├── words: 2/2 (匹配全部词)
├── proximity: 1 (词相邻)
├── attribute: name (最高优先级)
├── exact: 1 (部分精确)
└── custom: rating=4.8, popularity=9000
→ 排名: 第1

记录2: "iPhone 15"
├── typo: 0
├── words: 1/2 (只匹配"iphone")
├── proximity: N/A
├── attribute: name
├── exact: 1
└── custom: rating=4.7, popularity=8500
→ 排名: 第2

记录3: "iPhone Case"
├── typo: 0
├── words: 1/2 (只匹配"iphone")
├── proximity: N/A
├── attribute: name
├── exact: 1
└── custom: rating=4.5, popularity=5000
→ 排名: 第3

自定义排名 #

设置自定义排名 #

javascript
await index.setSettings({
  customRanking: [
    'desc(rating)',        // 评分降序
    'desc(popularity)',    // 人气降序
    'asc(price)'           // 价格升序
  ]
});

排名方向 #

方向 说明 适用场景
desc 降序 评分、人气、销量
asc 升序 价格、距离

排名策略 #

电商场景 #

javascript
customRanking: [
  'desc(popularity)',   // 热门商品优先
  'desc(rating)',       // 高评分优先
  'asc(price)'          // 同等条件下低价优先
]

内容场景 #

javascript
customRanking: [
  'desc(publishedAt)',  // 最新内容优先
  'desc(viewCount)',    // 高浏览量优先
  'desc(likeCount)'     // 高点赞数优先
]

用户场景 #

javascript
customRanking: [
  'desc(lastActiveAt)', // 最近活跃优先
  'desc(followers)',    // 高粉丝数优先
  'desc(posts)'         // 高发帖数优先
]

可搜索属性优先级 #

设置属性优先级 #

javascript
await index.setSettings({
  searchableAttributes: [
    'name',                        // 最高优先级
    'brand',                       // 中等优先级
    'description',                 // 较低优先级
    'unordered(category)'          // 不考虑位置
  ]
});

unordered修饰符 #

javascript
// 默认:考虑词的位置
// 查询 "phone case"
// "phone case" 排名高于 "case for phone"

// 使用unordered:不考虑位置
searchableAttributes: ['unordered(description)']
// "phone case" 和 "case for phone" 排名相同

相关性优化 #

1. 优化属性优先级 #

javascript
// 将重要属性放在前面
searchableAttributes: [
  'title',          // 标题最重要
  'keywords',       // 关键词次之
  'description'     // 描述最后
]

2. 使用自定义排名 #

javascript
// 根据业务需求设置排名
customRanking: [
  'desc(quality_score)',  // 质量分
  'desc(engagement)',     // 参与度
  'desc(freshness)'       // 新鲜度
]

3. 配置可选词 #

javascript
// 某些词不匹配也返回结果
index.search('iphone pro max', {
  optionalWords: ['pro', 'max']
});

4. 使用同义词 #

javascript
await index.saveSynonyms([
  {
    objectID: 'iphone-synonyms',
    type: 'synonym',
    synonyms: ['iphone', 'iPhone', '苹果手机']
  }
]);

5. 配置停用词 #

javascript
await index.setSettings({
  removeStopWords: ['en', 'zh']
});

排名调试 #

获取排名信息 #

javascript
const results = await index.search('iphone', {
  getRankingInfo: true
});

results.hits.forEach(hit => {
  console.log(hit.name, hit._rankingInfo);
});

排名信息字段 #

json
{
  "_rankingInfo": {
    "nbTypos": 0,
    "firstMatchedWord": 0,
    "proximityDistance": 1,
    "userScore": 100,
    "geoDistance": 0,
    "geoPrecision": 1,
    "nbExactWords": 1,
    "words": 1
  }
}
字段 说明
nbTypos 拼写错误数
firstMatchedWord 第一个匹配词的位置
proximityDistance 词的接近距离
userScore 自定义排名分数
geoDistance 地理距离(米)
words 匹配词数
nbExactWords 精确匹配词数

业务相关性 #

质量分数 #

javascript
// 预计算质量分数
{
  "qualityScore": 85,  // 综合质量分
  "rating": 4.8,
  "reviewCount": 1250,
  "returnRate": 0.02
}

// 用于排名
customRanking: ['desc(qualityScore)']

新鲜度 #

javascript
// 预计算新鲜度分数
{
  "freshness": 100,  // 新发布=100,随时间衰减
  "publishedAt": 1710432000
}

// 计算公式
freshness = 100 * exp(-decay_rate * days_since_publish)

个性化 #

javascript
// 启用个性化
index.search('iphone', {
  enablePersonalization: true,
  userToken: 'user-123',
  personalizationImpact: 50
});

排名规则 #

创建规则 #

javascript
await index.saveRule({
  objectID: 'promo-rule',
  condition: {
    pattern: 'sale',
    anchoring: 'contains'
  },
  consequence: {
    params: {
      filters: 'onSale:true',
      optionalFilters: ['brand:Apple<score=2>']
    }
  }
});

规则应用 #

text
查询: "iphone sale"
→ 应用规则
→ 过滤 onSale:true
→ Apple品牌加权

排名策略对比 #

策略 适用场景 配置
文本相关性 通用搜索 默认排名
业务优先 电商促销 customRanking
时间优先 新闻资讯 desc(publishedAt)
地理优先 本地服务 aroundLatLng
个性化 推荐系统 enablePersonalization

总结 #

排名与相关性要点:

要点 说明
排名公式 typo → geo → words → filters → proximity → attribute → exact → custom
自定义排名 customRanking配置
属性优先级 searchableAttributes顺序
调试工具 getRankingInfo参数
优化策略 属性优先级、自定义排名、同义词、可选词

接下来,让我们学习 基础搜索

最后更新:2026-03-28