`
zhouxi2010
  • 浏览: 51365 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

用xapian跟mmseg实现中文搜索

阅读更多

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数据库来获得最新的更新,要不然新添加的数据查不到

分享到:
评论
1 楼 ➸愛✘A'shIn信☠™ 2013-07-24  
你好,不知道在创建索引的时候效率怎么样,我创建1w条的时间大概是半小时。。。。感觉不正常。。

相关推荐

    网站搜索的进化PPT学习教案.pptx

    面对大量数据和频繁的搜索请求,数据库层面的搜索不再适用,于是出现了各种全文检索引擎工具和应用,如Lucene、Solr、Xapian、Nutch和Sphinx。这些工具提供了更高效、安全的搜索解决方案,其中,Lucene是一个开源的...

    03海量空间数据全文多模式检索技术研究(公开).ppt

    为了解决这一问题,姬英杰主讲的专业技术培训提出了“03海量空间数据全文多模式检索技术研究”,结合MMSEG中文分词技术和Xapian全文检索引擎,设计了一种创新的空间数据组织与检索方法。这种方法着重于提高对地理...

    《基于YOLOv8的八段锦练习指导系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    大语言模型教育应用中的知识冲突挑战与应对策略

    内容概要:本文详细探讨了大语言模型(LLMs)在教育应用中遇到的知识冲突问题,包括概念定义、事实陈述和逻辑推理层面的认知不一致性。文章分析了知识冲突的技术成因,如训练数据噪声、参数化知识表示的局限、推理机制的缺陷、模型架构的不足及外部知识的偏差,并探讨了这些因素对教育应用的深远影响。文中提出了多维度的解决路径,如通过数据增强优化知识表示、利用提示强化上下文连贯、开发量规完善模型评估等。此外,文章从社会文化的宏观视角剖析了知识冲突的外部驱动因素,探讨如何在多元异质、动态演进的社会建构语境中构建开放进取、兼容融通的智能教育应用体系。 适合人群:从事教育技术研究的学者、教育工作者、人工智能研究人员和技术开发者。 使用场景及目标:①帮助教育工作者理解大语言模型在教育应用中的局限性;②为技术人员提供优化大语言模型教育应用的具体策略;③促进教育人工智能技术的可靠性、适应性和普及性提升。 其他说明:文章强调了知识冲突的有效化解不仅能够提升大语言模型在教育场景中的应用价值,还将为人工智能在更广泛领域的可持续发展奠定坚实基础。

    《基于YOLOv8的家具鉴定系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    数据结构day1-思维导图顺序表

    数据结构day1-思维导图顺序表

    STM32超声波红外避障小车

    STM32超声波红外避障小车项目通过STM32微控制器实现自动避障功能。硬件部分主要包括STM32开发板、超声波传感器、红外传感器、直流电机、电池模块和电机驱动模块。超声波传感器用于测量前方障碍物的距离,红外传感器帮助小车检测地面线路或障碍物。电机驱动模块通过STM32控制直流电机的转动,从而实现小车的前进、后退和转向。 在软件方面,STM32通过编写简单的避障算法,实时读取传感器数据,并根据环境信息控制小车的运动。当超声波传感器检测到障碍物时,系统会触发后退或转向操作,避免碰撞。

    哈尔滨工业大学DeepSeek公开课-从图灵测试到DeepSeek.pdf

    哈尔滨工业大学DeepSeek公开课-从图灵测试到DeepSeek.pdf

    《基于YOLOv8的冰上运动监测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的体育产业监测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的港口机械识别系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    oooooomy_vchat_1742859071.zip

    app开发

    《基于YOLOv8的3D打印缺陷检测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    Screenshot_2025-03-31-19-36-01-657_com.UCMobile.jpg

    Screenshot_2025-03-31-19-36-01-657_com.UCMobile.jpg

    半导体过程控制篇 集成电路的可靠性仿真_03_31_153111.docx

    半导体过程控制篇 集成电路的可靠性仿真_03_31_153111.docx

    社交应用_鸿蒙OS_API12_高仿微信APP_开发示例_1742847098.zip

    社交应用_鸿蒙OS_API12_高仿微信APP_开发示例_1742847098.zip

    《基于YOLOv8的民间体育监测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    安卓_热更新_简化编译_HTHotFix框架_1742849446.zip

    app开发

    2024 最新版智慧消防全流程解决方案(含 BIM+IoT 技术应用 + 典型案例分析)

    2024 最新版智慧消防全流程解决方案(含 BIM+IoT 技术应用 + 典型案例分析)

    电商_微信小程序_学习项目_电商功能演示_1742849441.zip

    电商_微信小程序_学习项目_电商功能演示_1742849441.zip

Global site tag (gtag.js) - Google Analytics