音乐搜索的极致

48
音乐搜索的极致 唐福林 [email protected] http://blog.fulin.org

description

中国移动 12530 咪咕客户端 搜索

Transcript of 音乐搜索的极致

Page 1: 音乐搜索的极致

音乐搜索的极致

唐福林[email protected]://blog.fulin.org

Page 2: 音乐搜索的极致

目录

项目简介 需求描述 搜索实现 查询示例 持续改进

Page 3: 音乐搜索的极致

项目简介 (1/3) 中国移动 12530 咪咕 Miniportal 搜索 Out source : edadao

Page 4: 音乐搜索的极致

项目简介 (2/3) 时间: 2009 年 9 月 12 日到 10 月 22 日 地点:成都,郫县,犀浦,移动音乐基

地 参与人员:

需求提供: wangquanli@12530,  zhengchangsong@12530

开发人员: mike,tangfulin,xww,wanghui 特别贡献: dave

Page 5: 音乐搜索的极致

项目简介 (3/3) 部署情况:

位置:移动音乐基地,西区枢纽机房 机器:

建索引: 227.98 搜索: 227.221

Dual­Core AMD Opteron(tm) Processor 8218 2.6G * 8 8G mem Red Hat Enterprise Linux Server release 5.3 (Tikanga) Linux 2.6.18­128.el5PAE #1 SMP  i686 athlon  GNU/Linux

索引大小: 3 个索引目录共 1.2G 流量: 机器负载情况:

Page 6: 音乐搜索的极致

需求描述

搜索字段:歌手,歌曲,专辑,歌词 搜索方式:

精确匹配

前缀匹配

分词匹配

模糊匹配

拼音全量匹配

拼音首字母匹配

拼音同音匹配

拼音纠错匹配

关键词提示:• 搜索框下拉提示

• 纠错提示

Page 7: 音乐搜索的极致

需求-精确匹配

规则:精确匹配或过滤所有特殊字符后精确匹配

单个字段: 歌手:阿唬 , 80 前后 歌曲:爱情 BT 大讲堂 专辑: Alive!

多个字段联合: 歌手名+歌曲名:刘德华 今天 歌手名+专辑名:许茹芸 爱 . 旅行 . 一公里

Page 8: 音乐搜索的极致

需求-前缀匹配

规则:过滤所有特殊字符后前缀匹配 单个字段:

歌手:刘德,张学 歌曲: 专辑:

Page 9: 音乐搜索的极致

需求-分词匹配

规则:过滤所有特殊字符后分词匹配 单个字段:

歌手:德华,杰伦,学友 歌曲: 专辑: 歌词:

多个字段联合:先 Must ,再 Should 歌手名+歌曲名+专辑名: 歌手名+专辑名:

Page 10: 音乐搜索的极致

需求-模糊匹配

规则:一定模糊度的词匹配(注:很慢)

单个字段: 歌手:刘大华 歌曲: beautful, califonia 专辑:

Page 11: 音乐搜索的极致

需求-拼音全量匹配

规则:用户输入拼音匹配 单个字段:

歌手: liudehua, zhangxueyou 歌曲: 专辑:

Page 12: 音乐搜索的极致

需求-拼音首字母匹配

规则:用户输入拼音首字母匹配 单个字段:

歌手: ldh, zxy 歌曲: 专辑:

Page 13: 音乐搜索的极致

需求-拼音同音匹配

规则:用户拼音输入法,输入错误的同音字匹配

单个字段: 歌手:柳的话,两用器 歌曲: 专辑:

Page 14: 音乐搜索的极致

需求-拼音纠错匹配

规则:用户拼音输入法输入错误的字,或直接输入错误的拼音

n­l,h­f,z­zh,c­ch,s­sh,an­ang,en­eng,in­ing 单个字段:

歌手:牛德华, niudehua 歌曲: 专辑:

Page 15: 音乐搜索的极致

搜索实现

建索引策略 冗余字段 中文将拼音,首字母也建进索引里

搜索 Query 策略 弃用多次查询的策略 采用多个 Query 拼装成一个

BooleanQuery ,设置不同的权值,一次查询的策略

Page 16: 音乐搜索的极致

搜索实现:建索引策略 (1/2)

歌手: singer_name singer_name_save: 保存字段, trim 后,原封不动

singer_name_filtered:  过滤字段,过滤所有的特殊字符,转小写

singer_name_analyzed:  分词字段

singer_name_notanalyzed:  不分词字段,前缀匹配使用

singer_name_full:  拼音全量字段

singer_name_first:  拼音首字母字段

歌曲: song_name 

专辑: album_name 

Page 17: 音乐搜索的极致

搜索实现:建索引策略 (2/2)

关键词: keyword 所有的歌手名,歌曲名,专辑名,

歌手+歌曲,歌手+专辑,都视为关键词

单独一个索引文件 供下拉提示和搜索无结果时的纠错

提示使用 也提供拼音全量,拼音首字母,拼

音纠错等功能

Page 18: 音乐搜索的极致

搜索实现:搜索策略 (1/6)

策略列表:1. 精确匹配:歌手,歌曲,专辑,不分词字段,去掉前后多余空格,精确匹配

2. 过滤后的精确匹配:歌手,歌曲,专辑,过滤字段,去掉所有特殊字符,英文转成小写,精确匹配

3. 拼音全量匹配:歌手,歌曲,专辑,拼音全量字段,去掉所有非英文字符,英文转成小写,精确匹配

4. 同音纠错匹配:歌手,歌曲,专辑,拼音全量字段,只对含中文的搜索词使用,中文转拼音,英文转小写,去掉所有特殊字符,精确匹配

5. 拼音首字母匹配:歌手,拼音首字母字段,中文转拼音首字母,英文转小写,去掉所有特殊字符,精确匹配

6. 前缀匹配:歌手,歌曲,专辑,不分词字段,去掉前后多余空格,英文转小写,前缀匹配

7. 分词 Must 匹配:歌手,歌曲,专辑,(歌词),分词字段,分词,词之间使用 Must 连接,分词匹配

Page 19: 音乐搜索的极致

搜索实现:搜索策略 (2/6)

策略列表(续):1. 分词 Should 匹配:歌手,歌曲,专辑,(歌词),分词字段,分词,词之间使用

Should 连接,分词匹配

2. 合并分词 (must) 匹配:歌手+歌曲+专辑 分词字段,分词,(当前使用 must  连接),分词匹配

3. 合并分词 (should) 匹配:歌手+歌曲+专辑 分词字段,分词,(当前使用 Should  连接),分词匹配

4. 拼音纠错匹配查询(忽略掉鼻音等) : 歌手,歌曲,专辑,分词字段,去掉前后多余空格,英文转小写 .

5. 中文模糊匹配 ,中文时模糊度: 0.65: 歌手,歌曲,专辑,分词字段,去掉前后多余空格,英文转小写 .

6. 英文模糊匹配,英文模糊度: 0.85: 歌手,歌曲,专辑,分词字段,去掉前后多余空格,英文转小写 . 

Page 20: 音乐搜索的极致

搜索实现:搜索策略 (3/6)

精度选择 只搜索精确匹配结果

精确匹配,过滤后精确匹配,前缀匹配

拼音全量,首字母

分词全部命中

只搜索模糊匹配结果 分词部分命中

同音纠错,拼音纠错

模糊匹配

去掉精确匹配的结果

搜索全部结果

Page 21: 音乐搜索的极致

搜索实现:搜索策略 (4/6)

字段选择 只搜索歌手 只搜索歌曲 只搜索专辑 只搜索歌词 搜索关键词字段 搜索全部字段(暂时不包括关键词

和歌词)

Page 22: 音乐搜索的极致

搜索实现:搜索策略 (5/6)

设置权值 将所有的策略置入一个有序列表中 列表中相邻的两个策略之间权值相差常数倍(当前

设置为 10 )。过大可能会导致 lucene评分溢出,过小可能会导致不同策略命中的结果集重叠

调整列表中策略的先后次序以调整结果集中各种命中的出现顺序

二级权值:在搜索全部的时候,歌手 > 歌曲 > 专辑,所以需要在同一个策略内部再设置字段权值

中文分词命中的权值设置: Lucene 默认打分策略中,并没有考虑命中的词的长度。为了优先显示长的词命中的结果,对分词 Query 中每个词根据长度设置不同的权值

Page 23: 音乐搜索的极致

搜索实现:搜索策略 (6/6)

索引文件划分 搜索歌曲索引 搜索专辑索引 搜索关键词索引

排序策略 编辑置顶 Lucene 评分 业务量(点击,订阅,播放等) 关键词词频

Page 24: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,精确搜索 搜 刘德华,结果条数: 329

QUERY:(((singer_name_notanslysis: 刘德华 ^9.0 song_name_notanslysis: 刘德华 ^4.0 album_name_notanslysis: 刘德华 ))^10000.0) (((singer_name_filtered: 刘德华 ^9.0 song_name_filtered:刘德华 ^4.0 album_name_filtered: 刘德华 ))^1000.0) (((singer_name_filtered: 刘德华 *^9.0 song_name_filtered: 刘德华 *^4.0 album_name_filtered: 刘德华 *))^100.0) ((((((+singer_name_anslysis: 刘德华 +singer_name_anslysis: 德华 )^9.0) ((+song_name_anslysis: 刘德华 +song_name_anslysis: 德华 )^4.0) (+album_name_anslysis: 刘德华 +album_name_anslysis: 德华 ))))^10.0) ((((+singer_song_album: 刘德华 +singer_song_album: 德华 ))))

Page 25: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,精确搜索 搜 ldh ,结果条数: 401 (命中刘德华,刘大浩等)

QUERY:(((singer_name_notanslysis:ldh^9.0 song_name_notanslysis:ldh^4.0 album_name_notanslysis:ldh))^1000.00006) (((singer_name_filtered:ldh^9.0 song_name_filtered:ldh^4.0 album_name_filtered:ldh))^100.00001) (((singer_name_full:ldh^9.0 song_name_full:ldh^4.0 album_name_full:ldh))^10.000001) (((singer_name_first:ldh))^1.0000001) (((singer_name_filtered:ldh*^9.0 song_name_filtered:ldh*^4.0 album_name_filtered:ldh*))^0.10000001) ((((((+singer_name_anslysis:ldh)^9.0) ((+song_name_anslysis:ldh)^4.0) (+album_name_anslysis:ldh))))^0.010000001) (((((+singer_song_album:ldh))))^0.0010)

Page 26: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,精确搜索 搜 liudehua ,结果条数: 324 (歌名《我不是刘德华》无法命中)

QUERY:(((singer_name_notanslysis:liudehua^9.0 song_name_notanslysis:liudehua^4.0 album_name_notanslysis:liudehua))^1000.00006) (((singer_name_filtered:liudehua^9.0 song_name_filtered:liudehua^4.0 album_name_filtered:liudehua))^100.00001) (((singer_name_full:liudehua^9.0 song_name_full:liudehua^4.0 album_name_full:liudehua))^10.000001) (((singer_name_filtered:liudehua*^9.0 song_name_filtered:liudehua*^4.0 album_name_filtered:liudehua*))^1.0000001) ((((((+singer_name_anslysis:liudehua)^9.0) ((+song_name_anslysis:liudehua)^4.0) (+album_name_anslysis:liudehua))))^0.10000001) (((((+singer_song_album:liudehua))))^0.010000001) (((singer_name_first:liudehua))^0.0010)

Page 27: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,模糊搜索 搜 刘德华,结果条数: 44 (命中爱德华,杨德华等)

QUERY:­((((singer_name_notanslysis: 刘德华 ^9.0 song_name_notanslysis: 刘德华 ^4.0 album_name_notanslysis: 刘德华 ))^10000.0) (((singer_name_filtered: 刘德华 ^9.0 song_name_filtered: 刘德华 ^4.0 album_name_filtered: 刘德华 ))^1000.0) (((singer_name_filtered: 刘德华 *^9.0 song_name_filtered: 刘德华 *^4.0 album_name_filtered: 刘德华 *))^100.0) ((((((+singer_name_anslysis: 刘德华 +singer_name_anslysis: 德华 )^9.0) ((+song_name_anslysis: 刘德华 +song_name_anslysis:德华 )^4.0) (+album_name_anslysis: 刘德华 +album_name_anslysis: 德华 ))))^10.0) ((((+singer_song_album: 刘德华 +singer_song_album: 德华 ))))) +(((((singer_song_album:刘德华 ^9.0 singer_song_album: 德华 ^4.0)))^10000.0) (((((singer_name_anslysis: 刘德华^9.0 singer_name_anslysis: 德华 ^4.0)^9.0) ((song_name_anslysis: 刘德华 ^9.0 song_name_anslysis: 德华 ^4.0)^4.0) (album_name_anslysis: 刘德华 ^9.0 album_name_anslysis: 德华 ^4.0)))^1000.0) (((((singer_name_full:liudehua)^9.0) ((song_name_full:liudehua)^4.0) (album_name_full:liudehua)))^100.0) ((())^10.0) ((singer_name_anslysis: 刘德华 ~0.65^9.0 song_name_anslysis: 刘德华 ~0.65^4.0 album_name_anslysis: 刘德华 ~0.65)))

Page 28: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,模糊搜索 搜 牛德华,结果条数: 840 (命中刘德华,爱德华,杨德华等)

QUERY:­((((singer_name_notanslysis: 牛德华 ^9.0 song_name_notanslysis: 牛德华 ^4.0 album_name_notanslysis: 牛德华 ))^10000.0) (((singer_name_filtered: 牛德华 ^9.0 song_name_filtered: 牛德华 ^4.0 album_name_filtered: 牛德华 ))^1000.0) (((singer_name_filtered: 牛德华 *^9.0 song_name_filtered: 牛德华 *^4.0 album_name_filtered: 牛德华 *))^100.0) ((((((+singer_name_anslysis: 牛 +singer_name_anslysis: 德华 )^9.0) ((+song_name_anslysis: 牛 +song_name_anslysis: 德华 )^4.0) (+album_name_anslysis: 牛 +album_name_anslysis: 德华 ))))^10.0) ((((+singer_song_album: 牛 +singer_song_album: 德华 ))))) +(((((singer_song_album: 牛 singer_song_album: 德华 ^4.0)))^10000.0) (((((singer_name_anslysis: 牛 singer_name_anslysis: 德华 ^4.0)^9.0) ((song_name_anslysis: 牛 song_name_anslysis: 德华^4.0)^4.0) (album_name_anslysis: 牛 album_name_anslysis: 德华 ^4.0)))^1000.0) (((((singer_name_full:niudehua)^9.0) ((song_name_full:niudehua)^4.0) (album_name_full:niudehua)))^100.0) ((())^10.0) ((singer_name_anslysis: 牛德华 ~0.65^9.0 song_name_anslysis: 牛德华 ~0.65^4.0 album_name_anslysis: 牛德华 ~0.65)))

Page 29: 音乐搜索的极致

搜索示例

歌曲索引,全部字段,模糊搜索 搜 niudehua ,结果条数: 324 QUERY:­((((singer_name_notanslysis:niudehua^9.0 song_name_notanslysis:niudehua^4.0 

album_name_notanslysis:niudehua))^1000.00006) (((singer_name_filtered:niudehua^9.0 song_name_filtered:niudehua^4.0 album_name_filtered:niudehua))^100.00001) (((singer_name_full:niudehua^9.0 song_name_full:niudehua^4.0 album_name_full:niudehua))^10.000001) (((singer_name_filtered:niudehua*^9.0 song_name_filtered:niudehua*^4.0 album_name_filtered:niudehua*))^1.0000001) ((((((+singer_name_anslysis:niudehua)^9.0) ((+song_name_anslysis:niudehua)^4.0) (+album_name_anslysis:niudehua))))^0.10000001) (((((+singer_song_album:niudehua))))^0.010000001) (((singer_name_first:niudehua))^0.0010)) +(((((singer_song_album:niudehua^64.0)))^1000.0) (((((singer_name_anslysis:niudehua^64.0)^9.0) ((song_name_anslysis:niudehua^64.0)^4.0) (album_name_anslysis:niudehua^64.0)))^100.0) (((((singer_name_full:niudefua singer_name_full:liudehua)^9.0) ((song_name_full:niudefua song_name_full:liudehua)^4.0) (album_name_full:niudefua album_name_full:liudehua)))^10.0) ((singer_name_anslysis:niudehua~0.85^9.0 song_name_anslysis:niudehua~0.85^4.0 album_name_anslysis:niudehua~0.85)))

Page 30: 音乐搜索的极致

搜索示例

歌曲索引,歌手字段,精确搜索 搜 杰伦,结果条数: 270 QUERY:(((singer_name_notanslysis: 杰伦 ))^1000.0) (((singer_name_filtered: 杰伦 ))^100.0) 

(((singer_name_filtered: 杰伦 *))^10.0) ((((+singer_name_anslysis: 杰伦 ))))

Page 31: 音乐搜索的极致

搜索示例

歌曲索引,歌曲字段,模糊搜索 搜 li ,结果条数: 117  (命中 你 )

QUERY:­((((song_name_notanslysis:li))^10000.0) (((song_name_filtered:li))^1000.0) (((song_name_full:li))^100.0) (((song_name_filtered:li*))^10.0) ((((+song_name_anslysis:li))))) +(((((song_name_anslysis:li^4.0)))^100.0) ((((song_name_full:ni)))^10.0) ((song_name_anslysis:li~0.85)))

Page 32: 音乐搜索的极致

搜索示例

关键词索引,搜索歌曲 搜 liu ,结果:

流浪 流星 留恋 六月雪 浏阳河 流浪狗 流浪者之歌 留不住你的温柔

QUERY:+keyword_type:2 ­keyword_word_notanslysis:liu +(((keyword_word_filtered:liu*)^100.0) ((keyword_word_full:liu*)^100.0) ((keyword_word_first:liu*)^100.0))

Page 33: 音乐搜索的极致

搜索示例

关键词索引,搜索歌手 搜 liu ,结果:

刘德华 刘冠群 刘亦敏 刘韵 刘若英 刘基俊 刘益中 刘芳 刘庆

QUERY:+keyword_type:1 ­keyword_word_notanslysis:liu +(((keyword_word_filtered:liu*)^100.0) ((keyword_word_full:liu*)^100.0) ((keyword_word_first:liu*)^100.0))

Page 34: 音乐搜索的极致

搜索示例

关键词索引,搜索全部字段 搜 zhoujie ,结果:(有歌手+歌曲的命中)

周杰伦 周杰磊 周杰伦我求求你了 周杰伦传递祝福 周杰伦春节祝福 周杰伦情人节祝福

周杰伦 蒲公英的约定

周杰伦 最长的电影

周杰伦 阳光宅男

周杰伦 甜甜的

QUERY:+(keyword_type:1 keyword_type:2 keyword_type:3) ­keyword_word_notanslysis:zhoujie +(((keyword_word_filtered:zhoujie*)^100.0) ((keyword_word_full:zhoujie*)^100.0) ((keyword_word_first:zhoujie*)^100.0))

Page 35: 音乐搜索的极致

搜索示例

关键词索引,搜索全部字段 搜 柳的话,结果:(拼音同音命中)

刘德华 留得华

刘德华 冰雨

刘德华 中国人

刘德华 幸福这么远那么甜

刘德华 百分百好戏

刘德华 笑着哭

刘德华 谢谢你的爱

刘德华 爱你一万年

刘德华 情义俩心坚

QUERY:+(keyword_type:1 keyword_type:2 keyword_type:3) ­keyword_word_notanslysis:柳的话 +(((keyword_word_filtered: 柳的话 *)^100.0) (((keyword_word_full:liudehua*)^100.0) ((keyword_word_full:liudihua*)^100.0)))

Page 36: 音乐搜索的极致

持续改进 性能调优: resin ,内存, cache

汉字转拼音:多音字,特殊符号

拼音纠错:另一种思路,标准化 vs排列组合

关键词: Trie树,按词频排序,加入歌词数据

业务要求以频繁更新的业务量作为排序依据

标签搜索:新需求

搜索关键词,保持先后顺序

自定义打分算法的尝试

Lucene 升级到 2.9.1 , bug 1974 , explain 显示 0 或者 NaN

显示时最佳片段截取, html 实体截断问题

标红,按策略的山寨标红与 Lucene自带标红的优劣比较及取舍

Page 37: 音乐搜索的极致

性能调优

• 目标:单台机器,百万数量级的索引, 1000 个并发下, 99% 0.5秒内返回

• 优势:

• 索引更新不是很频繁,可以忽略不计

• 服务器性能不错, 8cpu , 8G内存

• 劣势:

• 并发大,返回时间 0.5秒要求太苛刻

• 一期代码有很多不合理的地方

• 项目时间紧张

• 使用了 resin作为容器,有太多不可控因素

Page 38: 音乐搜索的极致

汉字转拼音

• Pinyin4j  的词库

• 自己整理的多音字表

• 当前将所有多音字的组合都建在索引里

• 莫文蔚: mowenwei, mowenyu • 优点:保证能查到

• 缺点:输入 mowenyu  能查到莫文蔚,而且一个歌名中如果有好几个多音字,排列组合的数量比较可观

• 拼音首字母,而不是拼音声母

• 张学友: zxy ,不是 zhxy

Page 39: 音乐搜索的极致

拼音纠错

• 规则:

• n­l,h­f,z­zh,c­ch,s­sh,an­ang,en­eng,in­ing (on­ong)• 当前实现:

• 将用户输入的搜索词中的每个出现,依次替换成对应的纠错,联合成一个 Should Query

• 如: liudehua: niudehua, liudefua• 另一种思路:标准化

• 规定规则中的替换只能单向: n­>l,z­>zh 等

• 在索引中增加一个标准化拼音字段,如曾经最美,该字段存储的值为 chengjingzhuimei

• 用户输入关键词,也经过同样的标准化后,在该字段进行查询

Page 40: 音乐搜索的极致

关键词

• 关键词当前使用 Lucene  的索引前缀查询的方式实现

• 也包括拼音,首字母,纠错等 Query• 本来还有模糊查询的 Query ,但后来发现太影响查询

速度了,于是就暂时去掉了

• 当前没有把歌词数据建到关键词索引中去。如果把歌词建进去,这个索引就太大了,必须要进行分拆

• 考虑使用 Trie树:

• 多棵树,拼音,首字母,中文需要各自建树

• 模糊查询的问题

Page 41: 音乐搜索的极致

排序 vs更新• 业务需求希望能以歌曲的业务量(播放,下载等量)

作为排序的一个依据

• 意味着需要频繁的更新索引,而且为了更新这样一个数字字段,需要将整个文档删除重新添加,不划算

• 打算重载 Lucene  的 Collection 类,自己实现排序字段值的加载,不从索引里面读取

• 问题: 2.4  与 2.9 在这个地方的实现上有很大的不同,没法无缝切换

Page 42: 音乐搜索的极致

标签搜索

• 固定维度的标签,编辑填写,非用户产生内容

• 如:奥运,免费,铃声,开心,悲伤等

• 关键是产品设计,非技术实现

• 参考: google 泡泡挑歌

Page 43: 音乐搜索的极致

保持搜索关键词的顺序

• 延后实现的一个需求

• 只命中跟用户输入的多个关键词之间的顺序一致的结果

• 如:

• 用户输入 “谢谢 爱”命中“谢谢你的爱”,但输入 “爱 谢谢”不命中

• 用户输入 “眼睛 背叛 心”命中“你的眼睛背叛了你的心”,但输入“心 背叛 眼睛”不命中

• 实现:

• 分词命中,无法保留顺序信息

• 模糊查询,效率太差

• ???

Page 44: 音乐搜索的极致

打分算法

需求:

• 产品人员对Lucene打分算法的不理解,要求单纯的以某一个依据来进行排序,如命中的词的个数

• 拼多个Query查询的副作用:多个Query的评分累加得到的最后得分,会导致各个Query的命中结果重叠(想法:把累加改成取最大值?)

• 一个想法:同样的分词命中,命中较长的词的结果排前面

教训:• 没有金刚钻,别揽瓷器活!不要轻易的去改Lucene的评分算法

Page 45: 音乐搜索的极致

Lucene 版本的选择

• 首选 2.9.0• Bug 1974 :

https://issues.apache.org/jira/browse/LUCENE­1974• 换成了 2.4.1 • 为了性能及长远打算,还是希望换回 2.9.1• Explain  函数调用返回评分 0  或 NaN 

Page 46: 音乐搜索的极致

摘要截取

• Miniportal  空间有限,歌曲,专辑,甚至歌手名都可能需要截断

• 截断时需要考虑标红问题

• 截断时需要考虑 html  实体的问题

Page 47: 音乐搜索的极致

标红

• Lucene 标红的优点与不足

• 优点:正统,可升级

• 缺点:不能满足需求,前缀标红,拼音标红等

• 山寨标红

• 按照每种 Query 进行相应的标红,最后合并

Page 48: 音乐搜索的极致

http://blog.fulin.org

更多讨论