筹建一个知识分享平台(CS方面垂直搜索网站)初稿

搭建一个知识分享平台(CS方面垂直搜索网站)初稿

项目背景

有两类和我们大学生息息相关的产品。一类是微博,人人,豆瓣这些偏SNS的社交平台,推荐同学朋友的信息,帮助我们找到可能认识的人,可能喜欢的书,可能爱看的电影等等。另一类是学术相关的搜索引擎,比如Google Scholar,Microsoft Academic Search Engine,通过搜索关键字,提供一些匹配度最高的学术论文,给学习人员提供很多便利。

然而,学术搜索引擎是一个比较通用的工具,每个人搜索同一个词,给出的都是相同的Ranking List,不会像亚马逊一样根据用户的浏览和购书记录进行个性化推荐。基于这点,我的毕设内容是做一个带有用户个性化推荐性质的知识分享平台,在搜索到可能想要的结果之外,推荐给用户相关的学者,论文。同时,知识分享平台集成“众包”的理念,让用户去添加和分享自己感兴趣,想分享的知识,让平台更加社交化。


目标任务

目标是搭建一个知识分享平台,提供计算机科学方面的垂直搜索,具体内容,一方面是著名的专家学者的个人信息,也包括他的publications,个人主页等;另一方面是论文搜索结果,包括标题,全文等各个维度的检索功能。平台还允许并鼓励用户自己上传想要分享的论文,学者个人主页,并将获得这些数据,集成进平台底层数据中。在“众包”的效果下,用户还会发现与自己关注同相同领域,有着相似兴趣的其他用户,依照用户自己的搜索记录和分享记录,进行用户间的推荐,以及相关领域著名学者和论文的推荐。


问题分析

1.     平台的初始数据(学者和论文)需要自己爬取,并且具备一定的数据量。

2.     数据的存储除了一些存在于数据库的文本外,还要考虑pdf格式的论文在文件系统或者别的存储引擎的存储和获取。

3.     论文内全文的数据需要提取并且进行一定处理分析,为全文检索和推荐做好基础。

4.     平台分析学者个人主页时,要分析处理有效信息以及得到论文列表。

5.     需要为大规模的数据建立高效的索引。索引具备增量,近实时等特点。设计索引文档的结构,支持各维度的检索需求。

6.     平台以网站的方式呈现,要支持用户登录,提供快速的搜索体验,保证一定的搜索准确度。

7.     相关学者和论文的推荐需要做到尽可能好的效果。


初步技术方案

数据爬取

需求分析

数据需求是计算机科学方面的学者和论文元数据,所以我的爬取需求是定向的网络爬取,而不是通用的爬取。在调研,使用和对比了Nutch,Heritrix,Scrapy这些爬虫工具之后,决定采用Scrapy来做数据的爬取。


解决方案

Scrapy是一个Python写的爬虫框架,高效简单,代码量少,定制方便,而且是一个企业级的开源爬虫。相对于Nutch,Heritrix要轻量级很多,基本没有配置。它使用Python库中Twisted这个优秀的异步网络库来处理网络通讯,架构清晰,并且包含了各种中间件接口,可以灵活完成各种需求。

在爬数据的过程中,有两点还需要考虑。第一点是频繁的爬取会被目标站点发现,以至封掉爬虫机器的IP,简单的解决方案是在每两次页面抓取过程中加上适当的时间停顿,模拟人的浏览方式。第二点是数据的存储。Scrapy支持以json形式存储和读取爬取到的内容,我将把json对象存入MongoDB内,下面会具体介绍。


数据存储

需求分析

“学者”的数据大致包含以下一些字段:全名,工作地,个人主页,研究领域(多字段),论文列表(多字段)。“论文”的元数据信息大致包含:题目,摘要,作者(多字段),期刊,下载链接。如果让传统的面向行的关系型数据库,如MySQL,来存取数据,多字段会需要多张表之间的join操作,表之间需要外键关联,会影响查询性能。此外,可以适当放宽数据查询的一致性,只要满足CAP中的A和P。所以理想的存取方式是非结构化的存储,并且具备可用性和分布式可扩展性,达到最终一致性。


解决方案

MongoDB是当下比较热门的NoSQL之一。MongoDB是面向文档的NoSQL,也是易用性最高的。选择MongoDB,在解决以下几个问题中具备优势:

1.     MongoDB的存储模型是嵌套型的K/V对模型,称为BSON。通过pymongo驱动能和Scrapy轻松连接,并直接将json形式的数据存入数据库中。对于“学者”和“论文”,只要各自一个collection(相当于MySQL中的一张表)就能完成存储和查询需求。

2.     MongoDB有主从,分片的部署方式。主从集群中,从节点会自动备份当前活跃节点的数据,任何集群中的节点都有可能成为主节点,所以集群容错性强,且具备故障恢复的能力,这样的集群称为Replica Set。分片部署类似分布式部署,路由服务器会将多个分片节点与配置服务器相关联,且分片节点可简单增删,让集群具备高可扩展性,数据库的容量也得到了扩充。分片服务器还能根据指定的片键对指定数据库的collection读写做负载均衡。我将搭建一个健壮的MongoDB集群部署。

3.     MongoDB自带的GridFS用于存储较大的文件,“视觉中国”就利用该功能存储海量的图片。我将利用GridFS存储pdf格式的论文。

4.     MongoDB相比MySQL,还有更简洁的查询语言(实现在自带的js环境中),强大的基于MapReduce的查询等等。

 

索引

需求分析

搜索是平台提供的最主要服务,需要对学者,论文两块的元数据,以及论文的全文数据建立高效的索引,提供各个维度的搜索需求。考虑到论文也是结构比较清晰的一类全文数据,对于论文内部的各个章节的数据也需要工具来定向提取和分析处理,然后建立到索引内提供搜索。索引内可以存储部分数据,而大量的全文内容还是要存储在数据库内,所以索引和数据库之间也存在连结和交互。


解决方案

Lucene是一个java语言的搜索引擎库,为开发者提供了索引建立,搜索两块搜索引擎需要具备的基本功能。使用Lucene来自己定制索引块内的文档结构,为学者和论文定制索引,使用lucene的排序,高亮等功能,能搭建一套搜索原型了。

Solr兼容Lucene,将Lucene库进行了包装,封装成了一个可用的配置型搜索服务。在servlet容器(Tomcat,或者更轻量级的Jetty)中启动即可成为一个Http接口的搜索服务,能让搜索模块与网站隔离并且方便调用。Solr除了具备Lucene提供的一些搜索功能外,还提供批量的数据导入和自动建立索引,这里不涉及这块内容,因为索引的具体建立是由我利用Lucene自己建立的。我需要Solr的主要原因还是把它当作一个独立的搜索服务层。

除此之外,Apache Tika是一个内容抽取工具,我将使用Tika来抽取pdf内的论文全文内容,并进行处理和分析,将全文内容建立索引并存入MongoDB内,这些全文内容还可以服务于进一步挖掘论文之间的关系,涉及到相关推荐模块。

 

推荐/挖掘

需求分析

其实是基于研究方向,感兴趣领域的推荐,推荐内容可以是用户群,学者,论文。具体推荐这块如何做,用什么做还没有想好。也可能是一些关系的挖掘。


网站搭建

需求分析

网站的需求分析是相对简单的,能提供用户注册登陆,提供搜索框和搜索结果界面,提供用户上传和分享pdf或者url链接的页面。在整个工程中,网站搭建这块并不是重点,只是一个呈现形式。当然如果有时间尽量把他做得更简洁,更geek一点。


解决方案

在体验了一下Django之后,虽然他层次很清楚,开发便捷,可是考虑到我上述有比较多的java模块衔接,除了搜索可以作为服务外,别的小的模块还是需要融入到整个平台的代码里,所以暂时还是决定采用Spring+Struts2的框架来搭建这个平台。前台的技术和库基本上还是bootstrap,带上一些CSS3的东西。


结束语

我把整个工程作为我自己定的毕设内容。初衷是想把我自己实践过和想实践的工具/产品/技术都融合起来,让毕设成为一个沉淀技术积累和进一步学习新技术的过程。项目的代码都托管在我的github账户上,而且是公开的。
我一直贯彻着"需求推动技术"的想法。当我想做这个平台,并且手上已经有了很多爬来的数据的时候,开始考虑我是不是要去学习一些推荐系统方面的东西,我是不是需要去阅读一些相关论文,学习一下文本之间怎么挖掘,怎么根据主题去聚类分类,要用到什么样的算法。所以“推荐”,或者“挖掘”这块还没有具体想好。随着平台的搭建,一个产品原型出来了之后,自然会有更多的东西和可实践,可深化,可挖掘的东西。