最近对搜索引擎有了兴趣,这里把自己学习的过程记录一下。喜欢转载,但请注明出处和作者(南海十三郎)。

  分类:按规模分有internet(web)搜索引擎,企业级搜索引擎和个人桌面搜索引擎;按内容分有文字搜索引擎,图像/声频/视频等基于内容的搜索引擎。Web Search Engine是大家接触最多的Search Engine,Google百度就是这类了。个人桌面级的搜索引擎也有很多人在用,最常见的就是Google Desktop Search,(如果大家有好的推荐我一下)。普通用户最少接触到的就是企业级搜索引擎,这一部分应该是未来比较有发展的部分,我也是从接触企业级搜索引擎才关注这个领域的。企业级搜索又可以分为内部使用的搜索和对外提供服务的site search(站点搜索)。普通用户接触到的多数都是基于文本的搜索引擎(注意,是基于文本,不是基于语义semantic),目前普通用户接触到的图像/声频/视频搜索引擎基本是基于metadata的,真正基于内容的并且正确性还可以的搜索引擎并不多,应该说是没有。

  各种常见的搜索引擎请看这2个页面:

http://en.wikipedia.org/wiki/List_of_search_engines 

http://en.wikipedia.org/wiki/List_of_enterprise_search_vendors

  基于内容的搜索引擎请看这个页面:

http://en.wikipedia.org/wiki/List_of_CBIR_Engines

  最夸张的是还有硬件搜索引擎。我知道Fast公司有开发这种产品,搜索引擎卡,插到你的PC上,你PC上的内容就会在很短的时间内被index出来,这个技术后来被美国国防部收购了。Fast现在被微软收购,现在Fast的企业级搜索有被整合到SharePoint里)。

  

  组成:一个完整的搜索引擎由哪些部分组成。最粗的划分可以分为四个部分crawling(抓取),indexing(索引), storage(存储)和query(查询)。至于更详细的分,那就要细细道来了(其实还是粗略的说明,更细节的部分会在以后的文章里再陈述)。

  Crawling(抓取),说实话我不知道这个词要如何翻译才比较好。我觉得如果针对web搜索引擎那“嗅探”可能会更合适一些。所谓的引擎引擎是指在一定量(通常这个量比较大,至少要大到超出一般人的记忆力可以管理的范围)的数据中查找想要的数据。那么Crawling就是解决如何收集这些数据,如果将数据从数据源中抓取出来放到搜索引擎中的过程。因为对web搜索来看,它要处理的数据就是整个internet上的内容,所以,它要做的第一件事是要尽可能的把internet上的所有web页面的内容抓下来。所以,这个程序就是根据几个主要的起点(或是一个个扫描所有internet上的IP地址),把第一个页面抓下来,然后根据上面的链接去把更多的页面抓下来,再根据上面的链接再去把更更多的页面抓下来,然后再......。反正是试图把整个internet抓下来,不幸的是internet上的内容总是在新增,所以,这个艰巨而伟大的任务要一直执行下去。这个的行为是不是很像一只蜘蛛在网上爬?所以,这种程序也被称为网络蜘蛛(Web Spider)。对web搜索引擎来讲,只有web上的链接就可以了,但对企业和个人还有其它的数据源。如,数据库,个人邮箱,企业邮箱里的公共目录,个人磁盘上的文件系统,企业局域网里的共享文件目录,各种信息系统中的数据(ERP,CRM,MES,etc.),等等。所以,企业和个人搜索引擎的抓取系统,要有支持越多的系统和数据源才越好。对web搜索引擎的抓取系统,要抓的越广越深越快,就越好。除了把没爬过的数据抓来下,如果已经被爬过的有更新,那也要“嗅探”到并更新到搜索引擎里去。所以,对于已经爬过的内容,爬虫还是要定期的去重新检查一遍。

  Indexing(索引),数据通过Crawling从数据源中取到后,并不能直接放到Storage里。数据要经过一定的处理才能放到Storage里。在做Index之前,要将各种数据格式都转换成文本格式。什么word文档呀,Excel文档呀,PDF文档呀,JPEG文档呀,AVI文档呀,统统都要转成文本。没搞错吧,那些二进制格式怎么变成文本呀?嗯,当然没办法把那些图像和声音的内容转成文本,但是这些文件里都包含了一些metadata(例如记录何时拍的照片,作者是谁,属于哪张专辑),如果Metadata也没有,那文件名也算,总之多少总能找到一些有用的文本信息。然后,把这这些文本的里的标点符号统统去掉, 然后对这此文本进行分词处理(Tokenizer,各种语系的分词算法都不一样),分词过后得到的词元(Token)还要进经过语言处理(Linguistic Process)才会得到最终被称为Term(词)的东西交给"索引器" (Indexer),根据索引算法放到Storage里。具体怎么个索引法,这个太复杂,有空我们再讲。一些搜索引擎(特别是企业级搜索引擎)会在Crawling和Indexing之间也会做一些客制化的处理,使进行Indexing的数据更加结构化。

  Storage(存储),索引好的数据怎么存?首先,索引算法给如何存储数据定下了基本的规则。搜索引擎最大的特点是处理大量(海量)的数据,而且为了提高搜索的速度,以空间换时间这一最基本的技术就会被用上。所以,索引数据将会非常的庞大,索引后的数据通常是被索引数据的2~3倍以上。如果存储并有效的管理这些海量的数据,就是一个很大的挑战。首先,在索引算法中就会考虑增加一些压缩数据的方法,来减少索引后的数据大小。但这并不能从根本上解决问题,那么,分布式存储就是一个很的方法。例如Google的GFS和Apache的Hadoop。

  Query(查询),这是引擎中直接面向最终用户的地方。看上去只是用户输入一串字符,然后,就有结果显示出来。实现上"查询"是一个比较复杂的过程。首先,查询的步骤里,所有索引时的步骤几乎都会执行。Query拿到用户的输入后,就先做去标点(其实专业一点叫stop word,非常常用的字词也会作为stop word被抹掉的),分词,语言处理,把所有Term得到。但是,除了直接输入要查询的内容,多数搜索引擎还支持一些类似于SQL语言的查询语句。最常见的就是与(and),或(or),或是限定查询的范围(例如google的site:xxx, filetype:xxx)。Query需要对这些查询语句进行解释。接下来就是Query的关键是,把在Storage里的所有所包含Term的数据都找出来(因为有做indexing,Storage里的数据可以快速的被找到)。但是,对于一个包含海量数据的stogare,那被找出来的数据也可能是天文数字。所以,要对查到的数据与查询的字串做评分,然后根据评出来的分值对找到的数据进行排序。把分值高的放在前面呈现给最终用户。所以,这一部分才是一个搜索引擎好坏的关键。对与不同类型的搜索引擎,评分算法都不太一样。对于web搜索,google的反向链接评分算法,就是比较成功的一种。

  除这些主要的部分外,还有围绕这些模块或组件的管理和支持工具。

  搜索引擎的特别点就是能快速的处理非结构化数据的全文检索。从目前的技术水平来看,Crawling, indexing都是比较成熟的,大家的实现方法和方式没有本质的区别。Storage这部分,对于处理海量的web搜索,在费效比较方向还是有很大的挑战性的,目前处理的比较好的就是Google了。Apache有根据Google发表的论文实现了开源的Hadoop,所以,这部分也相对比较成熟(据说Baidu是用Hadoop)。Query的部分是目前最不成熟的部分,实现的方法多种多样,而且不同的类型之间的方法相互不适用。但是,有一点可以肯定,数据挖掘(data mining)和机器学习这些技术在越来越多的被引入到Query这部分上来。

  另外,关于搜索引擎的测试和比较,这是一个比较挑战的课目。应该说,没有比较好的方法,各种搜索引擎的设计各有长短,而且,对于搜索结果的评价是一个比较主观的标准。另一点,搜索引擎是通过海量数据来克服它的不准确性的,只有基于海量的数据,搜索引擎才能显现出优势来。