排名与相关性 #
排名机制概述 #
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