一个基于python的文本搜索引擎的设计和实现

这篇具有很好参考价值的文章主要介绍了一个基于python的文本搜索引擎的设计和实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

架构设计

下面是一个简单的搜索引擎的架构设计,包含了主要的组件和它们之间的关系。
该搜索引擎架构包括以下组件:
用户界面:这是用户与搜索引擎交互的部分,用户输入查询关键词,并通过用户界面得到搜索结果。
查询处理器:这是搜索引擎的核心组件,负责处理用户查询,将其转化为可执行的搜索操作,并向下游组件发送搜索请求。
索引器:负责维护搜索引擎的索引数据库,将文本文档转换为可搜索的数据结构。当查询处理器发出搜索请求时,索引器会使用索引数据库返回匹配的文档。
排名器:对于给定的查询,排名器根据相关性对搜索结果进行排序,以便向用户呈现最相关的结果。
爬虫:负责从互联网上收集文档,并将它们发送到索引器进行处理。
数据存储:用于存储索引数据库和其他搜索引擎数据的数据存储系统。
这个架构也可以进一步扩展和优化,例如可以添加负载均衡器来处理高流量,也可以使用分布式存储系统来处理大规模的索引数据库。

任务简化和需求分析

我们的目标是基于python实现核心的搜索功能,那么可以再对上面的架构再进行简化。首先从需求层面需要实现如下的功能:
1.我们实现的是搜索的核心功能,用户可以通过搜索函数的调用来获取搜索的结果(但这里我们不实现用户界面);搜索的字符串 - > 匹配的文本文件,并给出位置?
2.搜索的对象是多个文本文件,我们通过关键词的查询,匹配到最合适的结果并返回。那么如何匹配,我们常用的做法就是倒排索引。
3.关键词中的每个字都要进行匹配,对于索引出来的结果,需要整合和排名。
4.在引擎工作之前,我们需要先对所有的文档构建出索引。
5.选取合适的数据结构和存储技术,对索引进行存储。

技术上来说,需要实现:

  1. 搜索引擎类 simpleTxtSearchEngine
  2. 初始化方法,并在其中调用索引构建/更新;如果有持久化的操作,需要打开数据库进行相关操作;
    init / prepareIndex(倒排索引) / updateIndex / prepareIndexFromDB …
  3. 监听搜索动作,在发生时调用搜索 startSearch
  4. 提供 startSearch 所需要的 match 和 sort 等操作。

基于以上的步骤,开发、测试和联调,并迭代功能,提升性能。

编码

python hints:
@abstractmethod 装饰器语法,修饰抽象函数
_init_ 类构造函数,前后各加了双下划线。
__开头的属性是私有属性
类函数 @classmethod
def create_empty_book(cls, title, author):
return cls(title=title, author=author, context=‘nothing’)

raise Exception(‘get_context_length not implemented’) // 抛出异常。

第一个版本的代码实现如下(纯英文):

from abc import abstractmethod, ABCMeta, ABC
import os

class SearchEngineBase(ABC):
    def __init__(self):
        print('base')

    @abstractmethod
    def prepareIndex(self, dir):
        pass

    @abstractmethod
    def startSearch(self, queryWords):
        pass


class SearchEngineSimple(SearchEngineBase):
    def __init__(self, dir):
        super().__init__()
        self.dir = dir
        self.fileContents = {}

    def prepareIndex(self):
        #读取文本信息
        for filename in os.listdir(self.dir):
            if filename.endswith(".txt"):
                with open(os.path.join(self.dir, filename), "r") as file:
                    content = file.read()
                    print(content)
                    # 对读取的内容进行处理
                    # 可以将内容存储到一个列表或字典中
                    self.fileContents[filename] = content
        print(self.fileContents)

    def startSearch(self, queryWords):
        results = []
        # 遍历文件,查找关键字是否包含在其内。 返回命中的文件索引。
        for filename, content in self.fileContents.items():
            if queryWords in content:
                results.append(filename)
        return results

执行代码:

if __name__ == '__main__':
    simpleEngine = SearchEngineSimple("/Users/guanzhenwei/Desktop/pyTest/searchEng/")
    simpleEngine.prepareIndex()
  
    while True:
        query = input()
        print(query)
        results = simpleEngine.startSearch(query)
        print("matched files=" + ", ".join(results))

最新版本实现如下(基于倒排索引):

from abc import abstractmethod, ABCMeta, ABC
import os
import re

class SearchEngineBase(ABC):
    def __init__(self):
        print('base')

    @abstractmethod
    def prepareIndex(self, dir):
        pass

    @abstractmethod
    def startSearch(self, queryWords):
        pass

    @staticmethod
    def textToWords(text):
        # 使用正则表达式去除标点符号和换行符
        text = re.sub(r'[^\w ]', ' ', text)
        # 转为小写
        text = text.lower()
        # 生成所有单词的列表
        word_list = text.split(' ')
        # 去除空白单词
        word_list = filter(None, word_list)
        # 返回单词的 set, set自动去重。
        return set(word_list)

    @staticmethod
    def queryMatch(queryWords, words):
        queryWordList = SearchEngineBase.textToWords(queryWords)
        rtn = True
        for queryWord in queryWordList:
            if queryWord not in words:
                rtn = False
                break
        return rtn

# 这里的搜索是match,有顺序
class SearchEngineSimple(SearchEngineBase):
    def __init__(self, dir):
        super().__init__()
        self.dir = dir
        self.fileContents = {}

    def prepareIndex(self):
        # 读取文本信息
        for filename in os.listdir(self.dir):
            if filename.endswith(".txt"):
                with open(os.path.join(self.dir, filename), "r") as file:
                    content = file.read()
                    print(content)
                    # 对读取的内容进行处理
                    # 可以将内容存储到一个列表或字典中
                    self.fileContents[filename] = content
        print(self.fileContents)

    def startSearch(self, queryWords):
        results = []
        # 遍历文件,查找关键字是否包含在其内。 返回命中的文件索引。
        for filename, content in self.fileContents.items():
            if queryWords in content:
                results.append(filename)
        return results

# 这里的搜索是基于简单的词袋模型,无顺序。例如 character their 也会命中,原文中是 their character。
class SearchEngineV2(SearchEngineBase):
    def __init__(self, dir):
        super().__init__()
        self.dir = dir
        self.fileWordSets = {} # key为文件名, value为内容分解后的词集合。

    def prepareIndex(self):
        #读取文本信息
        for filename in os.listdir(self.dir):
            if filename.endswith(".txt"):
                with open(os.path.join(self.dir, filename), "r") as file:
                    content = file.read()
                    tempSet = self.textToWords(content)
                    # 对读取的内容进行处理
                    self.fileWordSets[filename] = tempSet
        print(self.fileWordSets)

    def startSearch(self, queryWords):
        results = []
        # 遍历文件,查找关键字是否包含在其内。 返回命中的文件索引。
        for filename, fileWordSet in self.fileWordSets.items():
            if self.queryMatch(queryWords, fileWordSet):
                results.append(filename)
        return results

# todo: 倒排索引和缓存。
# further: 支持中文分词,中英文混排和搜索。
class SearchEngineV3(SearchEngineBase):
    def __init__(self, dir):
        super().__init__()
        self.dir = dir
        self.wordIndexSets = {} # key为词, value为所在文件的集合。

    def prepareIndex(self):
        #读取文本信息
        for filename in os.listdir(self.dir):
            if filename.endswith(".txt"):
                with open(os.path.join(self.dir, filename), "r") as file:
                    content = file.read()
                    tempFileWordsSet = self.textToWords(content)
                    for word in tempFileWordsSet:
                        tempSet = self.wordIndexSets.get(word)
                        if tempSet:
                            tempSet.add(filename)
                        else:
                            tempSet = set()
                            tempSet.add(filename)
                            self.wordIndexSets[word] = tempSet
        print(self.wordIndexSets)

    def startSearch(self, queryWords):
        results = []
        # 对queryWords进行分词。
        queryWordList = self.textToWords(queryWords)

        interSet = set()
        for queryWord in queryWordList:
            matchSet = self.wordIndexSets.get(queryWord)
            if not matchSet:
                return []
            else:
                interSet = matchSet

        for queryWord in queryWordList:
            matchSet = self.wordIndexSets.get(queryWord)
            interSet.intersection_update(matchSet)

        return interSet



增加lrucache的版本:

class LRUCache(object):
    def __init__(self, size=32):
        self.cache = pylru.lrucache(size)

    def has(self, key):
        return key in self.cache

    def get(self, key):
        return self.cache[key]

    def set(self, key, obj):
        self.cache[key] = obj


class SearchEngineV3WithCache(SearchEngineV3, LRUCache):
    def __init__(self, dir):
        SearchEngineV3.__init__(self, dir)
        LRUCache.__init__(self)

    def startSearch(self, queryWords):
        if self.has(queryWords):
            print('hit cache!')
            return self.get(queryWords)
        else:
            result = SearchEngineV3.startSearch(self, queryWords)
            self.set(queryWords, result)
            return result

以上主要展现了python oop编程的思想和简单应用,可以看到python的灵活和强大。文章来源地址https://www.toymoban.com/news/detail-754830.html

到了这里,关于一个基于python的文本搜索引擎的设计和实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 毕设开题分享 基于python的搜索引擎设计与实现

    今天学长向大家分享一个毕业设计项目 毕业设计 基于python的搜索引擎设计与实现 项目运行效果: 毕业设计 基于python的搜索引擎 项目获取: https://gitee.com/sinonfin/algorithm-sharing 随着互联网和宽带上网的普及, 搜索引擎在中国异军突起, 并日益渗透到人们的日常生活中, 在互

    2024年01月24日
    浏览(49)
  • 智能科学毕设分享(算法) 基于python的搜索引擎设计与实现

    今天学长向大家分享一个毕业设计项目 毕业设计 基于python的搜索引擎设计与实现 项目运行效果: 毕业设计 基于python的搜索引擎 项目获取: https://gitee.com/assistant-a/project-sharing 随着互联网和宽带上网的普及, 搜索引擎在中国异军突起, 并日益渗透到人们的日常生活中, 在

    2024年02月20日
    浏览(59)
  • 基于Python与spimi的新闻搜索引擎设计与实现_kaic

    摘   要 在互联网还没有被普及的那个年代,人们查阅资料首先会想到去图书馆,而互联网的诞生,极大便利了人们查询信息的方式,搜索引擎打开了最有效的查询方法大门。  利用Python语言以及相关技术,实现了以新闻为主题的搜索引擎,完成这个项目要用到Python爬虫的多

    2024年02月07日
    浏览(47)
  • 软件工程毕设分享(含算法) 基于python的搜索引擎设计与实现

    今天学长向大家分享一个毕业设计项目 毕业设计 基于python的搜索引擎设计与实现 项目运行效果: 毕业设计 基于python的搜索引擎 项目获取: https://gitee.com/sinonfin/algorithm-sharing 随着互联网和宽带上网的普及, 搜索引擎在中国异军突起, 并日益渗透到人们的日常生活中, 在互

    2024年01月21日
    浏览(72)
  • 从零开始构建基于milvus向量数据库的文本搜索引擎

    在这篇文章中,我们将手动构建一个语义相似性搜索引擎,该引擎将单个论文作为“查询”输入,并查找Top-K的最类似论文。主要包括以下内容: 1.搭建milvus矢量数据库 2.使用MILVUS矢量数据库搭建语义相似性搜索引擎 3.从Kaggle下载ARXIV数据,使用dask将数据加载到Python中,并构

    2024年02月09日
    浏览(66)
  • ASP一个小型搜索引擎的设计与实现

           本文通过分析国内外搜索引擎的发展现状,提出了一种功能强大,操作简单,通用性强,可以满足用户对信息搜索需要,利用ASP技术实现的一个B/S体系结构的搜索引擎系统方案。文中着重论述了该系统的功能与实现、数据流程与存储、后台管理等。并对关键的有关技术

    2024年02月06日
    浏览(55)
  • Python实战之手写一个搜索引擎

    这篇文章,我们将会尝试从零搭建一个简单的新闻搜索引擎 当然,一个完整的搜索引擎十分复杂,这里我们只介绍其中最为核心的几个模块 分别是数据模块、排序模块和搜索模块,下面我们会逐一讲解,这里先从宏观上看一下它们之间的工作流程 数据模块的主要作用是爬取

    2024年02月02日
    浏览(50)
  • 基于java的搜索引擎系统设计与实现

    基于java的搜索引擎系统设计与实现 基于Java的搜索引擎系统设计与实现的研究背景和动机是构建一个高效、准确、安全的搜索引擎系统。随着互联网的普及,搜索引擎已经成为了人们获取信息的主要方式之一。但是,现有的搜索引擎系统还存在一些问题,比如搜索结果的准确

    2024年02月04日
    浏览(44)
  • 在云服务器ECS上用Python写一个搜索引擎

    一台阿里云ECS云服务器就是一台带有公网IP地址的计算机。用户可以通过远程登录使用这台计算机;同时,由于带有公网IP,用户在ECS云服务器上部署的网站、APP、小程序等,可以被其他人通过互联网访问。 本实验应用PageRank算法,使用Python,在一台ECS云服务器上搭建了一个简

    2024年02月03日
    浏览(52)
  • 基于Java的新闻全文搜索引擎的设计与实现

    中文摘要 本文以学术研究为目的,针对新闻行业迫切需求和全文搜索引擎技术的优越性,设计并实现了一个针对新闻领域的全文搜索引擎。该搜索引擎通过Scrapy网络爬虫工具获取新闻页面,将新闻内容存储在分布式存储系统HBase中,并利用倒排索引及轮排索引等索引技术对新

    2024年02月14日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包