coreseek/sphinx 全文检索实践指南

42
Coreseek/Sphinx 全全全全全全全全 李李李 2010-12-19

Upload: honestqiao

Post on 21-Jan-2015

3.961 views

Category:

Technology


0 download

DESCRIPTION

北京地区PHP爱好者2010聚会[12月19日胜利举办,CU、ThinkinginLamp联办],nzinfo主讲《Coreseek/Sphinx 全文检索实践指南》,详情见详情goo.gl/xCCxy或goo.gl/j89N9

TRANSCRIPT

Page 1: Coreseek/Sphinx 全文检索实践指南

Coreseek/Sphinx全文检索实践指南

●李沫南●2010-12-19

Page 2: Coreseek/Sphinx 全文检索实践指南

What will be covered?

A Introduction of Fulltext Search Brief Compare of Open Source FT Engines Why choose Sphinx Who using Sphinx

Page 3: Coreseek/Sphinx 全文检索实践指南

全文检索 VS 数据库检索 SELECT * FROM documents WHERE title like

'%test%' CPU 100% '30秒内只能进行一次查询 ' 没有找到记录 ...

如何解决? 为了提升数据库的性能,在某些字段上建索引 答案:在全文字段上加索引

Page 4: Coreseek/Sphinx 全文检索实践指南

数据库的全文索引 全文索引字段,数据库的标配功能

MySQL / PostgreqSQL SQL Server / Oracle

问题: 影响记录的存取性能 非标准的检索语法 切分规则? 排序规则? Too slow while indexing real-world dataset

Page 5: Coreseek/Sphinx 全文检索实践指南

No Magic - 倒排索引

比普通数据库检索快几倍 ~几百倍的性能提升 预读取、预切分 想想新华字典 倒排索引(反向索引)

Term1 → Doc1(pos1, pos2, pos...), Doc2, Doc3 …

正向索引 Doc1 → Term1(pos1, pos2, pos ...)

Page 6: Coreseek/Sphinx 全文检索实践指南

全文检索技术的宗教传统 线上的查经工具

http://abibletool.net/search.aspx 哥林多前书 13:8 "爱是恒久忍耐、又有恩慈.爱是

不嫉妒.爱是不自夸.不张狂. "

Page 7: Coreseek/Sphinx 全文检索实践指南

倒排索引历史 主后 1230 年,根据拉丁文 圣经 编制

主持者 Hugo de Sancto Charo 雨果 参与着 500 多人

主后 1550 年,第一部英文的词索引 编者 John Marbeck

计算机出现后,计算机辅助编制索引 70~80 年代, MAT 程序族

Page 8: Coreseek/Sphinx 全文检索实践指南

圣经倒排索引的假设 所有词语具有一样的重要性 不考虑词语出现的先后顺序 分章、分节 不考虑排序(按照出现的先后顺序排序)

Page 9: Coreseek/Sphinx 全文检索实践指南

全文检索的最简化模型 Word Of Bag

把文档作为一个口袋 Term是口袋中的元素 [假设 ]元素之间

地位平等 顺序无关 独立分布

Boolean 检索 非此即彼的二元世界观 a AND b, a OR b, a NOT b

Page 10: Coreseek/Sphinx 全文检索实践指南

全文检索 向量空间模型 把文档视为一个向量

Document Vector = {term1, term2, … termN} Query Vector = {term1, term2 }

Page 11: Coreseek/Sphinx 全文检索实践指南

全文检索 概率模型 TF/ IDF 算法

Okapi BM25 (BM = Best Match) Phrase Ranking

Page 12: Coreseek/Sphinx 全文检索实践指南

向量空间模型的优缺点优点

考虑到了 Term 出现的频率 相对更好的相关度排序

缺点 不适合处理超长文件

或者同一集合上,文件长度的尺寸差距很大 检索的 Term 必须完全匹配 不考虑语用(同义词、近义词) CJK 短语支持 ...

其他的模型?

Page 13: Coreseek/Sphinx 全文检索实践指南

开源检索系统的对比分析 开源传万世,因有我参与 常见开源的全文检索系统一览

Lucene / Nutch / Solr APL Sphinx / Coreseek GPL/商业授权 Xapian GPL Lemur (支持 Language Model) BSD

非主流 Zettair Terrier ....

Page 14: Coreseek/Sphinx 全文检索实践指南

如何评价检索系统? 检索精度( F-Score)

查全率、查准率(相关度) 可以处理的数据规模、系统架构 使用的检索模型(概率|向量空间|语言) 特性:

字段检索、自定义排序、属性过滤 正向索引?反向索引?分布式支持 接口的丰富程度 业务的其他需要

没有圣杯!

Page 15: Coreseek/Sphinx 全文检索实践指南

Why I choose Sphinx

Terabyte Index 良好的文档支持 与 LAMP软件栈紧密集成 唯一可选的 C/C++ 检索系统( @2006 ) Lucene 不适用于复杂检索(@2006) I hate Java

Page 16: Coreseek/Sphinx 全文检索实践指南

Sphinx (Coreseek)特性介绍( 1)

高速建立索引; 丰富的查询表达式( AND OR NOT 句子 段落

模糊 @字段) 多种结果后处理机制( Group By, Order By,

Custom Weighting ) 在生产环境中,千万篇文档, Tb级索引,数千

查询 /秒

Page 17: Coreseek/Sphinx 全文检索实践指南

Sphinx(Coreseek) 特性介绍( 2)

easy integration with SQL and XML data sources, and SphinxAPI, SphinxQL, or SphinxSE search interfaces;

easy scaling with distributed searches. Python data source adapter layer Build-in Chinese Tokenizer

Page 18: Coreseek/Sphinx 全文检索实践指南

Coreseek(Sphinx) VS Lucene

Coreseek ( Sphinx) 开箱即用的产品 ( LAMP ) 支持各种数据来源( via Python Source ) 内置中文分词( ... ) 商业支持

Lucene Java 人力成本低 库结构设计,修改容易 第三方工具? 分布式?

Page 19: Coreseek/Sphinx 全文检索实践指南

Sphinx VS Lucene

Faster Indexing Faster, more relevant searching SQL style queries We can do Java, but don`t require a Java stack. RT-Index VS. In memory Index

Page 20: Coreseek/Sphinx 全文检索实践指南

Sphinx 优势

BM25 Ranker phrase base ranking Boosts (sub) phrase matches Perfect match is guaranteed to be ranked #1 内置 Grouping 、分布式支持

Page 21: Coreseek/Sphinx 全文检索实践指南

Sphinx 限制

~ = 20 G , Per-single Index CRC64 WordID Field Mask, Only 24 Field Supported All attributes in memory! Poor windows support No inner cache support Hard to handle more than 3T data

Page 22: Coreseek/Sphinx 全文检索实践指南

吹牛时间(酒精考验的 Sphinx ) Boardreader.com

3KW 文档, 1M+ query/day

craigslist.com 20~30GB docs, 50M+ query/day

国内的实施 ChinaUnix Blogbus 51CTO 金融街 BBS .... Many site I never seen, due to Open Source ;-) 某档案馆检索( Tb )

Page 23: Coreseek/Sphinx 全文检索实践指南

A Short Break

Page 24: Coreseek/Sphinx 全文检索实践指南

Indexer 的流程

1.读取数据• 从数据库中读取• 用户主动 Push ( RTIndex )

2.Tokenizer• 西文 (词根、缩写的解读)• CJK (切分)

3.建立 [倒排 ]索引• 局部倒排• 合并

Page 25: Coreseek/Sphinx 全文检索实践指南

Check The Index

Use Search utility to query a index in cli Use index_tool to dump a index

Page 26: Coreseek/Sphinx 全文检索实践指南

索引文件格式(简介) .spi:

Dictionary (the complete list of wordid’s) .spa:

Attributes (only if docinfo=extern) .spd:

Document lists (for each keyword) .spp:

Hit lists (for each keyword) .spm:

MVA values

Page 27: Coreseek/Sphinx 全文检索实践指南

How Searching works

For each local index

Build a list of candidates (documents that satisfy the full-text query)

Filter (the analogy is WHERE)

Rank (compute the documents’ relevance values)

Sort (the analogy is ORDER BY)

Group (the analogy is GROUP BY)

Merge the results from all the local indexes

Page 28: Coreseek/Sphinx 全文检索实践指南

SQL 数据源:处理流程

Connected to the database Pre-query* : initial setup Main query : feed data Post-query : cleanup Disconnected Sorting ........ Connect to preform post-index & disconnected

Page 29: Coreseek/Sphinx 全文检索实践指南

MMSeg & Other Tokenizer (1)

MMSeg 的历史 从 CRFSeg 简化而来 早期阶段:内置集成 现在:外挂,仅处理中文 未来:全外挂

对配置的增加( index 节) charset_dictpath charset_type : zh_cn.utf-8 charset_debug

Page 30: Coreseek/Sphinx 全文检索实践指南

MMSeg & Other Tokenizer (2)

字段设置 prefix_fields

prefix_fields = url, domain infix_fields

Phrase 设置 phrase_boundary

phrase_boundary = ., ?, !, U+2026 phrase_boundary_step

Page 31: Coreseek/Sphinx 全文检索实践指南

构建索引( Indexer ) 执行

indexer --config csft.conf –all indexer --config csft.conf {the index name} indexer --config csft.conf {the index name} –rotate

定期重建 Crontab ? TaskKit (Python)

Now we have the index !!

Page 32: Coreseek/Sphinx 全文检索实践指南

Searchd .....

推荐的连接方式 Sphinx API

PHP Python Ruby Perl SphinxQL

MySQL 兼容客户端 Restful API

By Coreseek, in developing

Page 33: Coreseek/Sphinx 全文检索实践指南

Demo Code [PHP Client Side]Create a client objectSet up the optionsFire the query

<?php

include ( “sphinxapi.php” );

$cl = new SphinxClient ();

$cl->SetMatchMode ( SPH_MATCH_PHRASE );

$cl->SetSortMode ( SPH_SORT_EXTENDED, “price desc” );

$res = $cl->Query ( “ipod nano”, “products” );

var_dump ( $res );

?>

Page 34: Coreseek/Sphinx 全文检索实践指南

Demo Result [ PHP Client Side]Matches will always have document ID, weightMatches can also have numeric attributes* No string attributes yet (pull them from MySQL)

print_r ( $result[“matches”][0] ):

Array ([id] => 123[weight] => 101421[attrs] => Array (

[group_id] => 12345678901[added] => 1207261463 ) )

Page 35: Coreseek/Sphinx 全文检索实践指南

DB Vs. Sphinx Who take the job?

SQL query parts that can be moved to Sphinx

Filtering – WHERE vs. SetFilter() or fake keyword Sorting – ORDER BY vs. SetSortMode() Grouping – GROUP BY vs. SetGroupBy()

Up to 100x (!) improvement vs. “naïve” approach

Rule of thumb – move everything you can from MySQL to Sphinx

Page 36: Coreseek/Sphinx 全文检索实践指南

Sphinx Searching pipeline

Search, WHERE, rank, ORDER/GROUP “Cheap” boolean searching first Then filters (WHERE clause) Then “expensive” relevance ranking Then sorting (ORDER BY clause) and/or grouping

(GROUP BY clause)

Page 37: Coreseek/Sphinx 全文检索实践指南

Group By (1)

SetGroupBy SetGroupDistinct

Page 38: Coreseek/Sphinx 全文检索实践指南

Group By – SetGroupBy(2)

function SetGroupBy ( $attribute, $func, $groupsort="@group desc" )

$attribute: read which attribute $func: 加工 $attribute

SPH_GROUPBY_[DAY|WEEK|MONTH|YEAR] SPH_GROUPBY_ATTR

$groupsort: Sort the grouping order.

Page 39: Coreseek/Sphinx 全文检索实践指南

Group By – SetGroupDistinct(3)

function SetGroupDistinct ( $attribute ) $cl->SetGroupBy ( "category",

SPH_GROUPBY_ATTR, "@count desc" ); $cl->SetGroupDistinct ( "vendor" );

SELECT id, weight, all-attributes, COUNT(DISTINCT vendor) AS @distinct,COUNT(*) AS @countFROM productsGROUP BY categoryORDER BY @count DESC

Page 40: Coreseek/Sphinx 全文检索实践指南

结果高亮( BuildExcerpts ) function BuildExcerpts ( $docs, $index, $words,

$opts=array() ) before_match | after_match

$docs : 要高亮的文本,数组形式 $index: 制定文本切分方案 $words: 要高亮的词 @return 高亮的结果,数组形式 高亮的问题?

Page 41: Coreseek/Sphinx 全文检索实践指南

索引规划 近实时索引

Main + Delta

实时索引 Main + RTIndex

数据分区 按板块 按时间 按 docID

Page 42: Coreseek/Sphinx 全文检索实践指南

Q&A

【 Future Discussion】 Tokenizer 分布式索引 性能开销 同一功能,不同的实现 (Attribute Vs. Fake word)