1 / 44

搜索引擎解密

搜索引擎解密. 猎兔搜索 罗刚. 搜索引擎结构. 文件. 文档. 文本提取. 索引程序. 数据库. 索引库 (Lucene). 爬虫. 搜索查询服务器 (Solr). NBA. 搜索. Lucene 是什么. 包括 全文索引库 简单的语言解析功能 不包括 爬虫 文档格式解析 “PageRank” 等排序算法. Lucene 来源与发展. 1999 Cutting 开发的第一个 Java 程序 2001 捐赠给 Apache 2004 年 11 月 1.4.3 版本 2008 年 10 月 2.4.0 版本

jewel
Télécharger la présentation

搜索引擎解密

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 搜索引擎解密 猎兔搜索 罗刚

  2. 搜索引擎结构 文件 文档 文本提取 索引程序 数据库 索引库(Lucene) 爬虫 搜索查询服务器(Solr) NBA 搜索

  3. Lucene是什么 • 包括 • 全文索引库 • 简单的语言解析功能 • 不包括 • 爬虫 • 文档格式解析 • “PageRank”等排序算法

  4. Lucene来源与发展 1999 Cutting 开发的第一个Java程序 2001 捐赠给Apache 2004年11月 1.4.3版本 2008年10月 2.4.0版本 2009年11月 3.0.0版本

  5. Lucene的用户 • 国际 Twitter IBM LinkedIn 捐出分类统计的子项目bobo-browse和 实时搜索的项目Zoie • 国内 凤凰网 敦煌网 豆丁

  6. 人工编的名词索引-方便查找

  7. 词: 文档: 北京 1 2 上海 武汉 3 天津 大连 4 5 全文索引结构

  8. Lucene中的倒排索引

  9. 索引相关类 Document Analyzer IndexWriter Field(Title) Field(URL) Field(Body) • 通过IndexWriter来写索引,通过IndexReader读索引。 • 一段有意义的文字需要通过Analyzer分割成一个个词语后才能按关键词搜索。Analyzer就是分析器,StandardAnalyzer是Lucene中最常用的分析器。 •  TokenStream实例保存着当前的Attribute状态。 Attribute 是一个接口,实现中包含一个代表词本身含义的字符串和该词在文章中相应的起止偏移位置, Attribute还可以用来存储词类型或语义信息。 •  一个Document代表索引库中的一条记录。要搜索的信息封装成Document后通过IndexWriter写入索引库。调用Searcher接口按关键词搜索后,返回的也是一个封装后的Document的列表。 •  一个Document可以包含多个列,叫做field。例如一篇文章可以包含“标题”、“正文”、“修改时间”等field,创建这些列对象以后,可以通过Document的add方法增加这些列。

  10. Analyzer Analyzer analyzer = new StandardAnalyzer(); // or any other analyzer TokenStream ts = analyzer.tokenStream("myfield",new StringReader("some text goes here")); while (ts.incrementToken()) { System.out.println("token: "+ts)); }

  11. 创建索引 //创建新的索引或者对已有的索引增加文档 index = new IndexWriter(indexDirectory, new StandardAnalyzer(Version.LUCENE_CURRENT), !incremental, IndexWriter.MaxFieldLength.UNLIMITED); File dir = new File(sSourceDir); indexDir(dir); //索引路径 index.optimize();//索引优化 index.close();//关闭索引库

  12. 向索引增加文档 Document doc = new Document(); //创建网址列 Field f = new Field("url", news.URL , Field.Store.YES, Field.Index. NOT_ANALYZED,//不分词 Field.TermVector.NO); doc.add(f); //创建标题列 f = new Field("title", news.title , Field.Store.YES, Field.Index.ANALYZED,//分词 Field.TermVector.WITH_POSITIONS_OFFSETS);//存Token位置信息 doc.add(f); //创建内容列 f = new Field("body", news.body , Field.Store.YES, Field.Index. ANALYZED, //分词 Field.TermVector.WITH_POSITIONS_OFFSETS); //存Token位置信息 doc.add(f); index.addDocument(doc);

  13. 搜索 // read-only=true IndexSearcher isearcher = new IndexSearcher(directory, true); // Parse a simple query that searches for "text": QueryParser parser = new QueryParser(Version.LUCENE_CURRENT,"fieldname", analyzer); Query query = parser.parse("text"); //返回前1000条搜索结果 ScoreDoc[] hits = isearcher.search(query, 1000).scoreDocs; //遍历结果 for (int i = 0; i < hits.length; i++) { Document hitDoc = isearcher.doc(hits[i].doc); System.out.println(hitDoc.get("fieldname")); } isearcher.close(); directory.close();

  14. 常用查询

  15. 区间查询 查询语法: time:[2007-08-13T00:00:00Z TO 2008-08-13T00:00:00Z] 调用代码: ConstantScoreRangeQuery dateQuery = new ConstantScoreRangeQuery("time", t1, t2, true, true);

  16. 2.9以前版本区间查询的问题 RangeQuery采用扩展成TermQuery来实现,如果查询区间范围太大,RangeQuery会导致TooManyClausesException ConstantScoreRangeQuery 内部采用Filter来实现,当索引很大的时候,查询速度会很慢

  17. Trie结构实现的区间查询 4 5 6 42 44 52 63 64 421 423 445 446 448 521 522 632 633 641 642 644 Range 在Lucene2.9以后的版本中,用Trie结构索引日期和数字等类型。例如:把521 这个整数索引成为:百位是5、十位是52、个位是521。这样重复索引的好处是可以用最低的精度搜索匹配区域的中心地带,用较高的精度匹配边界。这样减少了要搜索的Term数量。

  18. Trie结构区间查询 例如:TrieRange:[423 TO 642]分解为5个子条件来执行: handreds:5 OR tens:[43 TO 49] OR ones:[423 TO 429] OR tens:[60 TO 63] OR ones:[640 TO 642]

  19. 查询语法 加权 solr^4 lucene 修饰符 + - NOT +solr lucene 布尔操作符 OR AND (solr OR lucene) AND user 按域查询 title:NBA

  20. QueryParser QueryParser将输入查询字串解析为Lucene Query对象。 QueryParser是使用JavaCC(Java Compiler Compiler )工具生成的词法解析器。 QueryParser.jj中定义了查询语法。 需要让QueryParser更好的支持中文,例如全角空格等?

  21. Filter 可以定义Filter类来过滤查询结果。也可以缓存和重用Filter。如下条件可用Filter来实现: 根据不同的安全权限显示搜索结果; 仅查看上个月的数据; 在某个类别中查找。

  22. BestDriversFilter BestDriversFilter 把结果限定到score 是5 的司机。 public class BestDriversFilter extends Filter{ @Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException { OpenBitSet bitSet = new OpenBitSet( reader.maxDoc() ); TermDocs termDocs = reader.termDocs( new Term( "score", "5" ) ); while ( termDocs.next() ) { bitSet.set( termDocs.doc() ); } return bitSet; } }

  23. 使用Filter Filter bestDriversFilter = new BestDriversFilter(); //query不变,增加bestDriversFilter ScoreDoc[] hits = isearcher.search(query, bestDriversFilter, 1000).scoreDocs; //返回的结果可能比以前少了

  24. 分类统计(Faceted Search)

  25. Filter实现的分类统计 String[] cats = {"001004003","001008003021","001004014" }; //类别数组 long[] catCounts = new long[cats.length];//分类统计结果 //原始查询 Filter all = new QueryWrapperFilter(q); //用AND逻辑合并Filter ChainedFilter.DEFAULT = ChainedFilter.AND; for (int i=0;i<cats.length;++i) { //分类统计查询条件 Filter these = new QueryWrapperFilter(new TermQuery(new Term("cat", cats[i]))); ChainedFilter chainedFilter = new ChainedFilter( new Filter[]{all,these} ); //取得Filter中的BitSet的1 的个数 catCounts[i] = chainedFilter.getCardinality(reader); } return catCounts;

  26. Solr vs Sphinx Sphinx速度很快,但是不支持索引复制和分发。有单点失败的问题 Sphinx不支持搜索结果的高亮显示 Sphinx没有对搜索结果的缓存 个人结论: Sphinx功能简单,速度快,Solr速度慢点,但功能更全。

  27. Solr起源 Lucene仅仅是一个全文检索包,不是一个独立的搜索服务 Solr来源于CNET.com的内部数据库检索项目 Solr的含义是:"Searching On Lucene w/Replication "   Solr当前主要主要代码维护者Yonik斯坦福大学硕士毕业

  28. Solr发展过程 2004秋天,CNET启动Solr项目的前生Solar 2005夏天,CNET产品目录搜索开始使用Solar 2006年1月捐赠给Apache 2007年1月Solr毕业成为Lucene的子项目并发布1.2版本 2008年9月发布 1.3.0版本 2009年11月发布1.4版本

  29. Solr用户 • 国际 • AOL • CNET • Disney • Apple, Inc. • 国内 • 阿里巴巴 • 安居客 • 新聚思(SYNNEX)

  30. Solr搜索服务器的特点 是Web Server中的Servlet 积极的缓存(自动加载搜索热词等) Web管理界面 XML/HTTP, JSON 接口 Faceting(分类统计搜索结果) 通过Schema配置文件定义types 和 fields 为了并发访问,实现主从式的索引复制

  31. 使用Solr搜索服务器 • Java客户端-SolrJ • 通过Java 二进制格式快速返回结果 • .Net客户端-SolrSharp • PHP客户端-“solr-php-client”

  32. Schema.xml <field name="id" type="string" indexed="true" stored="true" multiValued="false" /> <field name="title" type="text_ws" indexed="true" stored="true" multiValued="false" /> <field name="body" type="text_ws" indexed="true" stored="true" multiValued="false" />

  33. Schema.xml 指定id为唯一列 <uniqueKey>id</uniqueKey> 指定body为默认搜索列。 <defaultSearchField>body</defaultSearchField>

  34. solrconfig.xml 用来配置solr运行的系统参数,例如缓存,插件等。 预热搜索数量最好少于CPU核数量 <maxWarmingSearchers>4</maxWarmingSearchers>

  35. 增加数据 HTTP POST to http://localhost:8983/solr/update/ <add> <doc> <field name="employeeId">05991</field> <field name="office">Bridgewater</field> <field name="skills">Perl</field> <field name="skills">Java</field> </doc> [<doc> ... </doc>[<doc> ... </doc>]] </add>

  36. 更新/删除数据 • 更新 • 若增加文档的主键已经存在索引库中,则替换已有的。 • 删除 • 通过主键删除 <delete><id>05991</id></delete> • 通过查询删除 <delete> <query>name:Anthony</query> </delete> • <Commit/> • <Optimize/>

  37. Solr的后台管理界面

  38. Solr后台查询实例 查询用时 查询条件 查询结果数 查询(Query),根据查询条件可以得到查询结果,例如*:*

  39. Search • 基本参数 • qt – 查询类型 (request handler),例如 standard • wt – 返回格式类型(response writer),例如xml或json • 公共参数 • q – 查询词 • sort – 排序方式 • start - 返回结果的开始行 • rows -本次需要返回结果的行数 • fl – 需要返回的列名称

  40. Faceted Search http://localhost:8983/solr/select?q=ipod&rows=0&facet=true&facet.limit=-1&facet.field=cat&facet.mincount=1&facet.field=inStock <response> <responseHeader> <status>0</status> <QTime>3</QTime> </responseHeader> <result numFound="4" start="0"/> <lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"> <lst name="cat"> <int name="music">1</int> <int name="connector">2</int> <int name="electronics">3</int> </lst> <lst name="inStock"> <int name="false">3</int> <int name="true">1</int> </lst> </lst> </lst> </response>

  41. 搜索界面

  42. 检索案例 • http://www.xiaoxishu.com/ • (前端PHP) http://www.alljournals.cn/ (前端.net)

  43. 商业支持 • Lucene • http://www.searchblox.com • Solr • http://www.lucidimagination.com • http://www.lietu.com

  44. 谢谢!http://www.lietu.com

More Related