xapian是一个开源的信息检索项目,类似于lucence,官网地址:http://xapian.org/。
安装:用apt-get可以在ubuntu里安装如下模块:
apt-xapian-index - maintenance tools for a Xapian index of Debian packages
libxapian15 - Search engine library
python-xapian - Xapian search engine interface for Python
如果是用django,可以安装:python-django-djapian - Search API for Django using Xapian
mmseg是一个国人写的中文分词模块,网址:http://pypi.python.org/pypi/mmseg/1.3.0;
用mmseg加上xapian就可以实现中文搜索的功能了。
好了,在我的项目中,原始数据是保存在数据库中的,所以需要从数据库中读出数据,再来建立索引,所以建立索引的代码如下:
class Index(object): def __init__(self, DBPATH, host='localhost', user='dbuser', passwd='dbpasswd', dbname='pjname'): self.SEARCH_DB = xapian.WritableDatabase(DBPATH, xapian.DB_CREATE_OR_OPEN) self.conn = MySQLdb.connect(host=host, user=user, passwd=passwd, db=dbname, charset='utf8') def _add_hanzi(self, doc, data): if not data: return for word, value in seg_txt_2_dict(data).iteritems(): doc.add_term(word, value) def modify_data(self, data_dict): for k, v in data_dict.items(): if not v: data_dict[k] = '' if isinstance(v, int): data_dict[k] = str(v) if isinstance(v, datetime.date): data_dict[k] = u'%04d%02d%02d' %(v.year, v.month, v.day) if isinstance(v, Decimal): data_dict[k] = str(v) return data_dict def _update_index(self, data_dict): data_dict = self.modify_data(data_dict) doc = xapian.Document() for k, v in data_dict.items(): if k in ('name', 'author', 'isbn'): self._add_hanzi(doc, v) key = 'I%s'%data_dict['id'] doc.add_term(key) data = simplejson.dumps(data_dict, encoding='utf8') doc.set_data(data) self.SEARCH_DB.replace_document(key, doc) def update_index(self): for row in self.get_database_value(): self._update_index(row) def get_database_value(self): cursor = self.conn.cursor() count = 0 keys = ['id', 'name', 'isbn', 'price', 'pulisher', 'publish_date', 'img_url', 'description', 'author'] while True: cursor.execute('select bb.id as id, bb.name as name, isbn, price, publisher, publish_date, img_url, description, group_concat(ba.name) as author from book_book as bb left join book_book_author as bba on bb.id=bba.book_id left join book_author as ba on bba.author_id=ba.id group by bb.id limit %s,%s', (count*1000, 1000)) data = cursor.fetchall() count = count + 1 if not data or count > 1000: break for value in data: value_d = dict(zip(keys, value)) yield value_d
索引建立后就可以搜索了,下面是搜索的代码(还实现了结果分页的功能):
class Search(object): def __init__(self, DBPATH): self.SEARCH_DB = xapian.Database(DBPATH) self.SEARCH_ENQUIRE = xapian.Enquire(self.SEARCH_DB) def _get_enquire_mset(self, start_offset, end_offset): try: return self.SEARCH_ENQUIRE.get_mset(start_offset, end_offset) except xapian.DatabaseModifiedError: self.SEARCH_DB.reopen() return self.SEARCH_ENQUIRE.get_mset(start_offset, end_offset) def _get_document_data(self, document): try: return document.get_data() except xapian.DatabaseModifiedError: self.SEARCH_DB.reopen() return document.get_data() def _get_hit_count(self): return self._get_enquire_mset(0, self.SEARCH_DB.get_doccount()).size() def search(self, keywords, start_offset=0, end_offset=None): query_list = [] if isinstance(keywords, unicode): keywords = keywords.encode('utf8') for word, value in seg_txt_2_dict(keywords).iteritems(): query = xapian.Query(word, value) query_list.append(query) if len(query_list) != 1: query = xapian.Query(xapian.Query.OP_AND, query_list) else: query = query_list[0] self.SEARCH_ENQUIRE.set_query(query) count = self.SEARCH_DB.get_doccount() if not end_offset: end_offset = count - start_offset matches = self._get_enquire_mset(start_offset, end_offset) results = [] for match in matches: data = self._get_document_data(match.document) data = simplejson.loads(data, encoding='utf8') results.append(data) return {'count': self._get_hit_count(), 'object_list':results} def search_by_page(self, keywords, pagenum=1, num_per_page=20): if pagenum < 1: pagenum = 1 start_offset = (pagenum - 1) * num_per_page end_offset = num_per_page data = self.search(keywords, start_offset, end_offset) data['has_previous'] = pagenum >1 and True or False data['previous_page_number'] = pagenum > 1 and pagenum - 1 or 1 data['number'] = pagenum data['has_next'] = pagenum*num_per_page < data['count'] and True or False data['next_page_number'] = pagenum + 1 data['paginator'] = {'num_pages': (data['count']+num_per_page-1) / num_per_page} return data
在django使用搜索功能:
def search_book(request): search_words = request.REQUEST.get('search_words') try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 if request.method == 'POST': page = 1 books = SEARCH.search_by_page(search_words, page) t=get_template('book/search_result.html') c=RequestContext(request,locals()) return HttpResponse(t.render(c))
备注:xapian是单写多读,所以最好单独做索引的建立,所以建立后不会立即写入硬盘,可以用flush完成
query的时候需要定时reopen数据库来获得最新的更新,要不然新添加的数据查不到
相关推荐
Xapian中文资料少之又少,这篇文章可以说很对xapian全方位的做了介绍,浅显易懂,学xapian必备。
以Xapian 为核心开发一个搜索程序,以13 年第一季度的新浪新闻为检索目标,自行设计文档解析程序、调用xapian 建索引并实现一般检索、以及一个特殊的修饰符搜索功能(如url 搜索、标题搜索、时间搜索等),程序运行...
Xapiand:一个基于Xapian的RESTful搜索引擎
xapian的使用 配合我的blog文章的一个小demo 希望各位下载者能够从中明白如何使用xapian
1.2.1 垂直搜索的应用场景 1.2.2 垂直搜索的技术选型 1.2.3 垂直搜索的引擎架构 1.2.4 垂直搜索技术和业务细节 1.2.5 现场答疑【Q&A】 2、知识扩展 2.1 淘宝类目及标题相关性分档计算方法 2.1.1 系统预测该关键词所...
由于xapian的Python版中的示例只是简单的从命令行获取输入而不是文件系统,我在网上搜集了一些资料,终于写出一个可用的python+xapian,可以对整个目录进行索引。
C++开源搜索引擎xapian开发入门demo
Xapian是一个用C++编写的全文检索程序,他的作用类似于Java的lucene。Windows下VS编译doxygen需要此库。
由于Xapian-1.2.22 windows下在官网暂时没人维护,自己通过不断尝试,在vs2005下加入新增的cc文件,最终编译通过
基于Xapian和PHP的高性能站内搜索系统方案设计
了解如何在Windows上编译和使用Xapian搜索技术及其陷阱。
它根据安装的的版本确定要使用的xapian-bindings的版本。 下载并提取源代码; 然后运行./configure , make和make install 。 该项目与项目没有任何关系。安装确保在系统上安装了必要的构建和开发工具。 确保通过...
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
Xapian::机架Xapian::Rack 提供了一个机架中间件,... 要执行搜索: query = request[:query] || ""search = Xapian::Rack.get(request.env)results = Xapian::Rack.find(request.env, query, {:options => Xapian::Qu
acts_as_xapian:Xapian全文搜索插件,适用于Ruby on Rails
使用这个包可以在你的 Django 项目中进行全文搜索。 版本兼容性矩阵: 贾皮安 姜戈 夏平 <= 2.2.4 1.0 1.0.2 <= 2.3.1 1.1 1.0.7 >= 2.4 1.2.1 1.2 注意:在 mod_python 环境中 Xapian (< ...
xapian_text_index
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
Omseek已重命名为Xapian。 Xapian是一个用C ++编写的搜索引擎库,带有Perl,Python,PHP,Java,Tcl,C#和Ruby的绑定。 它使您可以轻松地向应用程序添加高级索引和搜索功能。
是一个用C ++编写的开源搜索引擎库。 Xapian是一个高度适应性强的工具包,它使开发人员可以轻松地在其自己的应用程序中添加高级索引和搜索功能。 Xapian图书馆 安装Xapian库本身。 在Gentoo Linux中emerge dev-libs...