用Python实现一个大数据搜索引擎

python下建立elasticsearch索引实现大数据搜索——之编程实现(二) 我们的编程思路是: 1.首先根据用户的需求提出的主图案,颜色,技法,我们应该在素材resource表中找到包含有这三种需求的素材list 2.然后根据素材list的每一个素材,在设计图stylepatternshow表中找到包含有该种素材的设计图 所以总体上需要两个类,一个是ElasticMaterialObj类,能够根据需求找到素材list;另一个是ElasticGraphObj类,能够根... 阅读详情

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。

布隆过滤器 (Bloom Filter)

第一步我们先要实现一个布隆过滤器。

布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的数据中,那么它可以以很快的速度返回目标不存在。

让我们看看以下布隆过滤器的代码:

class Bloomfilter(object):
    """
    A Bloom filter is a probabilistic data-structure that trades space for accuracy
    when determining if a value is in a set.  It can tell you if a value was possibly
    added, or if it was definitely not added, but it can't tell you for certain that
    it was added.
    """
    def __init__(self, size):
        """Setup the BF with the appropriate size"""
        self.values = [False] * size
        self.size = size

    def hash_value(self, value):
        """Hash the value provided and scale it to fit the BF size"""
        return hash(value) % self.size

    def add_value(self, value):
        """Add a value to the BF"""
        h = self.hash_value(value)
        self.values[h] = True

    def might_contain(self, value):
        """Check if the value might be in the BF"""
        h = self.hash_value(value)
        return self.values[h]

    def print_contents(self):
        """Dump the contents of the BF for debugging purposes"""
        print self.values
  • 基本的数据结构是个数组(实际上是个位图,用1/0来记录数据是否存在),初始化是没有任何内容,所以全部置False。实际的使用当中,该数组的长度是非常大的,以保证效率。
  • 利用哈希算法来决定数据应该存在哪一位,也就是数组的索引
  • 当一个数据被加入到布隆过滤器的时候,计算它的哈希值然后把相应的位置为True
  • 当检查一个数据是否已经存在或者说被索引过的时候,只要检查对应的哈希值所在的位的True/Fasle

看到这里,大家应该可以看出,如果布隆过滤器返回False,那么数据一定是没有索引过的,然而如果返回True,那也不能说数据一定就已经被索引过。在搜索过程中使用布隆过滤器可以使得很多没有命中的搜索提前返回来提高效率。

我们看看这段 code是如何运行的:

bf = Bloomfilter(10)
bf.add_value('dog')
bf.add_value('fish')
bf.add_value('cat')
bf.print_contents()
bf.add_value('bird')
bf.print_contents()
# Note: contents are unchanged after adding bird - it collides
for term in ['dog', 'fish', 'cat', 'bird', 'duck', 'emu']:
    print '{}: {} {}'.format(term, bf.hash_value(term), bf.might_contain(term))

结果:

[False, False, False, False, True, True, False, False, False, True]
[False, False, False, False, True, True, False, False, False, True]
dog: 5 True
fish: 4 True
cat: 9 True
bird: 9 True
duck: 5 True
emu: 8 False

首先创建了一个容量为10的的布隆过滤器

然后分别加入 ‘dog’,‘fish’,‘cat’三个对象,这时的布隆过滤器的内容如下:

然后加入‘bird’对象,布隆过滤器的内容并没有改变,因为‘bird’和‘fish’恰好拥有相同的哈希。

最后我们检查一堆对象('dog', 'fish', 'cat', 'bird', 'duck', 'emu')是不是已经被索引了。结果发现‘duck’返回True,2而‘emu’返回False。因为‘duck’的哈希恰好和‘dog’是一样的。

分词 

下面一步我们要实现分词。 分词的目的是要把我们的文本数据分割成可搜索的最小单元,也就是词。这里我们主要针对英语,因为中文的分词涉及到自然语言处理,比较复杂,而英文基本只要用标点符号就好了。

下面我们看看分词的代码:

def major_segments(s):
    """
    Perform major segmenting on a string.  Split the string by all of the major
    breaks, and return the set of everything found.  The breaks in this implementation
    are single characters, but in Splunk proper they can be multiple characters.
    A set is used because ordering doesn't matter, and duplicates are bad.
    """
    major_breaks = ' '
    last = -1
    results = set()

    # enumerate() will give us (0, s[0]), (1, s[1]), ...
    for idx, ch in enumerate(s):
        if ch in major_breaks:
            segment = s[last+1:idx]
            results.add(segment)

            last = idx

    # The last character may not be a break so always capture
    # the last segment (which may end up being "", but yolo)    
    segment = s[last+1:]
    results.add(segment)

    return results

主要分割

主要分割使用空格来分词,实际的分词逻辑中,还会有其它的分隔符。例如Splunk的缺省分割符包括以下这些,用户也可以定义自己的分割符。

] < > ( ) { } | ! ; , ' " * \n \r \s \t & ? + %21 %26 %2526 %3B %7C %20 %2B %3D -- %2520 %5D %5B %3A %0A %2C %28 %29

def minor_segments(s):
    """
    Perform minor segmenting on a string.  This is like major
    segmenting, except it also captures from the start of the
    input to each break.
    """
    minor_breaks = '_.'
    last = -1
    results = set()

    for idx, ch in enumerate(s):
        if ch in minor_breaks:
            segment = s[last+1:idx]
            results.add(segment)

            segment = s[:idx]
            results.add(segment)

            last = idx

    segment = s[last+1:]
    results.add(segment)
    results.add(s)

    return results

次要分割

次要分割和主要分割的逻辑类似,只是还会把从开始部分到当前分割的结果加入。例如“1.2.3.4”的次要分割会有1,2,3,4,1.2,1.2.3

def segments(event):
    """Simple wrapper around major_segments / minor_segments"""
    results = set()
    for major in major_segments(event):
        for minor in minor_segments(major):
            results.add(minor)
    return results

分词的逻辑就是对文本先进行主要分割,对每一个主要分割在进行次要分割。然后把所有分出来的词返回。

我们看看这段 code是如何运行的:

for term in segments('src_ip = 1.2.3.4'):
        print term
src
1.2
1.2.3.4
src_ip
3
1
1.2.3
ip
2
=
4

搜索

好了,有个分词和布隆过滤器这两个利器的支撑后,我们就可以来实现搜索的功能了。

上代码:

class Splunk(object):
    def __init__(self):
        self.bf = Bloomfilter(64)
        self.terms = {}  # Dictionary of term to set of events
        self.events = []
    
    def add_event(self, event):
        """Adds an event to this object"""

        # Generate a unique ID for the event, and save it
        event_id = len(self.events)
        self.events.append(event)

        # Add each term to the bloomfilter, and track the event by each term
        for term in segments(event):
            self.bf.add_value(term)

            if term not in self.terms:
                self.terms[term] = set()
            self.terms[term].add(event_id)

    def search(self, term):
        """Search for a single term, and yield all the events that contain it"""
        
        # In Splunk this runs in O(1), and is likely to be in filesystem cache (memory)
        if not self.bf.might_contain(term):
            return

        # In Splunk this probably runs in O(log N) where N is the number of terms in the tsidx
        if term not in self.terms:
            return

        for event_id in sorted(self.terms[term]):
            yield self.events[event_id]
  • Splunk代表一个拥有搜索功能的索引集合
  • 每一个集合中包含一个布隆过滤器,一个倒排词表(字典),和一个存储所有事件的数组
  • 当一个事件被加入到索引的时候,会做以下的逻辑
    • 为每一个事件生成一个unqie id,这里就是序号
    • 对事件进行分词,把每一个词加入到倒排词表,也就是每一个词对应的事件的id的映射结构,注意,一个词可能对应多个事件,所以倒排表的的值是一个Set。倒排表是绝大部分搜索引擎的核心功能。
  • 当一个词被搜索的时候,会做以下的逻辑
    • 检查布隆过滤器,如果为假,直接返回
    • 检查词表,如果被搜索单词不在词表中,直接返回
    • 在倒排表中找到所有对应的事件id,然后返回事件的内容

我们运行下看看把:

s = Splunk()
s.add_event('src_ip = 1.2.3.4')
s.add_event('src_ip = 5.6.7.8')
s.add_event('dst_ip = 1.2.3.4')

for event in s.search('1.2.3.4'):
    print event
print '-'
for event in s.search('src_ip'):
    print event
print '-'
for event in s.search('ip'):
    print event
src_ip = 1.2.3.4
dst_ip = 1.2.3.4
-
src_ip = 1.2.3.4
src_ip = 5.6.7.8
-
src_ip = 1.2.3.4
src_ip = 5.6.7.8
dst_ip = 1.2.3.4

是不是很赞!

更复杂的搜索

更进一步,在搜索过程中,我们想用And和Or来实现更复杂的搜索逻辑。

上代码:

class SplunkM(object):
    def __init__(self):
        self.bf = Bloomfilter(64)
        self.terms = {}  # Dictionary of term to set of events
        self.events = []
    
    def add_event(self, event):
        """Adds an event to this object"""

        # Generate a unique ID for the event, and save it
        event_id = len(self.events)
        self.events.append(event)

        # Add each term to the bloomfilter, and track the event by each term
        for term in segments(event):
            self.bf.add_value(term)
            if term not in self.terms:
                self.terms[term] = set()
            
            self.terms[term].add(event_id)

    def search_all(self, terms):
        """Search for an AND of all terms"""

        # Start with the universe of all events...
        results = set(range(len(self.events)))

        for term in terms:
            # If a term isn't present at all then we can stop looking
            if not self.bf.might_contain(term):
                return
            if term not in self.terms:
                return

            # Drop events that don't match from our results
            results = results.intersection(self.terms[term])

        for event_id in sorted(results):
            yield self.events[event_id]


    def search_any(self, terms):
        """Search for an OR of all terms"""
        results = set()

        for term in terms:
            # If a term isn't present, we skip it, but don't stop
            if not self.bf.might_contain(term):
                continue
            if term not in self.terms:
                continue

            # Add these events to our results
            results = results.union(self.terms[term])

        for event_id in sorted(results):
            yield self.events[event_id]

利用Python集合的intersection和union操作,可以很方便的支持And(求交集)和Or(求合集)的操作。

运行结果如下:

s = SplunkM()
s.add_event('src_ip = 1.2.3.4')
s.add_event('src_ip = 5.6.7.8')
s.add_event('dst_ip = 1.2.3.4')

for event in s.search_all(['src_ip', '5.6']):
    print event
print '-'
for event in s.search_any(['src_ip', 'dst_ip']):
    print event
src_ip = 5.6.7.8
-
src_ip = 1.2.3.4
src_ip = 5.6.7.8
dst_ip = 1.2.3.4

 

总结

以上的代码只是为了说明大数据搜索的基本原理,包括布隆过滤器,分词和倒排表。如果大家真的想要利用这代码来实现真正的搜索功能,还差的太远。所有的内容来自于Splunk Conf2017。大家如果有兴趣可以去看网上的视频。

如何做一个基于 Python 的搜索引擎? 做一个基于Python的搜索引擎需要多方面的知识和技术,包括爬虫技术、数据处理技术、搜索算法、缓存技术、分布式系统、搜索引擎优化技术、机器学习算法、自然语言处理技术等。以上是一个基本的搜索引擎建立流程,具体实现需要根据具体需求和情况进行调整和优化。 阅读详情

相关推荐

python下建立elasticsearch索引实现大数据搜索——之编程实现(三)

Go on....... 接下来我们来实现ElasticGraphObj类,上面已经得到包含有相关需求的素材list,那么该类的目的是根据得到的material list可以找到相应的设计graph 3. ElasticGraphObj类 3.1 __init__方法 def __init__(self,index_name,index_type,ip="127.0.0.1"): ...

m0_37673307的博客 1680

基于python的新闻搜索引擎设计与实现

21世纪的今天互联网信息技术飞速发展,各类信息充斥着互联网,如何有效的进行信息的搜集整理成为了一个非常重要的课题。网络爬虫就是实现自动搜索互联网中的各种信息的程序,本系统通过定向的对新闻网站相关的信息进行采集分析与展示。运用计算机图形学及影像处理高新技术,数字可视化能够以图像的形式展现给用户,从而让用户能够轻松地获取、分析、掌握、应用相关的知识。它不仅能够帮助用户快速、准确地获取所需的资讯,还能够让用户能够轻松地了解到所需的信息,从而提升用户的工作效率。

yvonneking1118的博客 2709

python实现搜索引擎

【代码】python实现搜索引擎。

weixin_44772948的博客 502

Python实战之手写一个搜索引擎

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

2301_80239908的博客 2115

安卓直链APK安装拦截全解析:从Play Protect到厂商管控的应对指南

在移动应用分发领域,APK(Android Package)安装是开发者与用户交互的关键环节。其核心原理涉及安卓系统的安全沙箱机制与权限管理体系,旨在保护用户设备免受恶意软件侵害。这一机制的技术价值在于平衡了应用生态的开放性与安全性,但也在应用推广、企业内部分发等场景中带来了挑战。尤其在通过官网、广告等直链渠道分发APK时,常会遇到安装转化率骤降的问题。这背后主要受到Google Play Protect云端扫描、安卓系统安装权限模型演进(如Android 8.0+的安装源授权)以及设备制造商附加安全层(如

weixin_33894640的博客 470

服务器卡死排查实战:从现象分类到根因定位的完整手册

服务器卡死是运维中最令人头疼的故障之一,从游戏圈吐槽的“土豆服务器”到生产环境中的Linux系统无响应、rsync复制挂起,本质都是系统或进程失去正常响应能力。其原理通常涉及CPU、内存、磁盘IO或网络资源耗尽,以及内核和驱动异常。掌握系统化的排查方法,能够帮助工程师快速定位根因、缩短故障时间,避免盲目重启。本文从资源、层级、场景等多维度分类,结合top、dmesg、strace等工具,梳理一套从现象确认、指标收集、日志分析到进程定位的实战排查流程,并覆盖常见高频场景与预防治理建议。无论你是运维新手还是老手

weixin_33851177的博客 377

用74l138实现一个一位全减器_用Python实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。01布隆过滤器 (Bloom Filter)第一步我们先要实现一个布隆过滤器。布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在于我的数据中,那...

weixin_36027600的博客 700

开启虚拟人物互动新时代:探索相芯Avatar SDK驱动功能(Android)

相芯SDK提供了男孩和女孩Avatar驱动模型,这些模型具备半身驱动和全身驱动的功能,使得虚拟角色能够根据用户的面部表情和动作实时模仿和响应。半身驱动功能: 相芯SDK的男孩和女孩Avatar驱动模型具备上身驱动功能,即能够通过用户的面部表情和动作来驱动虚拟角色的上半身行为。这意味着用户的面部表情、头部转动和上半身姿态等动作可以直接映射到虚拟角色上,使得虚拟角色能够栩栩如生地模仿用户的动作。例如,用户微笑时,虚拟角色会展现出笑容;用户转动头部时,虚拟角色也会相应地转动头部。

Faceunity2023的博客 633

教你如何用 Python 来实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (Bloom Filter) 第一步我们先要实现一个布隆过滤器。 布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的

海牛大数据的博客 3412

Delphi开发者必备:CEF4Delphi跨平台浏览器嵌入实战指南(含Lazarus适配)

本文详细介绍了Delphi开发者如何利用CEF4Delphi实现跨平台浏览器嵌入,包括环境配置、Lazarus适配、ARM架构优化及Firemonkey集成等实战技巧。通过Chromium引擎的强大功能,开发者可以轻松为传统桌面应用添加现代浏览器特性,提升多平台开发效率。

weixin_29233333的博客 230

手把手教你解决Ubuntu 20.04虚拟机桥接模式下的网络问题:DHCP与静态IP配置全指南

本文详细解析了Ubuntu 20.04虚拟机在桥接模式下的网络配置问题,包括DHCP与静态IP的配置方法及常见故障排查技巧。通过深入讲解桥接模式原理和提供实战操作指南,帮助用户解决无法访问外网、ping不通等典型网络问题,实现虚拟机与物理网络的无缝连接。

weixin_29256771的博客 545

python实现全网搜索_用Python实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。布隆过滤器 (Bloom Filter)第一步我们先要实现一个布隆过滤器。布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的数据中,那么它可以以很快...

weixin_39714565的博客 1670

Kylin V10 ARM64离线安装ffmpeg实战指南

在国产化替代浪潮下,基于银河麒麟V10和ARM架构(如飞腾、鲲鹏)的内网服务器部署音视频处理服务成为常态。由于系统默认软件源缺乏aarch64包且无法连接外网,常规yum安装方式难以奏效。本文从离线安装的通用概念出发,剖析了在Kylin V10上安装ffmpeg的三大路线及其原理,重点介绍了源码编译法,包括依赖梳理、工具链准备、编译参数配置、常见错误排查等关键环节。同时,将这套依赖管理与离线部署方法论延伸至nginx、node.js、Python库及docker等场景,帮助读者建立一套可复用的国产化系统离线

weixin_33417488的博客 148

用 Python 实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (Bloom Filter) 第一步我们先要实现一个布隆过滤器。 布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说

大数据公社 1622

字符串尾部空格的迷思:深入解析 ABAP 隐式转换规则与 `strlen` 意外结果

看似简单的strlen之谜,背后实则是 ABAP 隐式转换的一整套严谨规则。只要开发者在赋值、输出、接口映射等关键节点建立“尾部空格意识”,辅以CONVCONDENSE等显式手段,就能有效杜绝多余空格引发的链式故障。希望本文的拆解与案例,能让你在面对下一个“异常长度”时,从容而笃定地给出正确答案。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 435

31、Labview如何搭建程序框架?--状态机到数据采集等常用框架

本文废话不多,直接列举几种框架搭建方式,为了尽量向大家提供干货,本文直接从简介和手把手教搭建框架两方面来讲解,本文提到五种经典框架模式,学会这五种就很够了,分别是:状态机框架(State Machine)、生产者-消费者框架(Producer-Consumer)、主-从框架(Master-Slave)、事件驱动框架(Event-Driven)、分层架构(Layered Architecturep)。这个框架是基于状态机结构的。顾名思义“状态机”就是个“切换程序状态的机器”。本质是一个。

关注我,更多技术问题欢迎私聊~ 3105

大数据毕设分享 基于python的搜索引擎设计与实现

今天学长向大家分享一个毕业设计项目毕业设计 基于python的搜索引擎设计与实现毕业设计 基于python的搜索引擎随着互联网和宽带上网的普及, 搜索引擎在中国异军突起, 并日益渗透到人们的日常生活中, 在互联网普及之前, 人们查阅资料首先想到的是拥有大量书籍的资料的图书馆。但是今天很多人都会选择一种更方便、 快捷、 全面、 准确的查阅方式–互联网。而帮助我们在整个互联网上快速地查找到目标信息的就是越来越被重视的搜索引擎。今天学长来向大家介绍如何使用python写一个搜索引擎,该项目常用于毕业设计。

mabile123444的博客 1259

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

python毕业论文大数据_浅谈用Python实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。布隆过滤器 (Bloom Filter)第一步我们先要实现一个布隆过滤器。布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的数据中,那么它可以以很快...

weixin_39638309的博客 1117

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【技术分享】用Python实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (Bloom Filter) 第一步我们先要实现一个布隆过滤器。 布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的数据中,那么...

jiawoxuexiqq30294961的博客 225

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

python elasticsearch模块_Python 操作 ElasticSearch

Python操作ElasticSearchPython批量向ElasticSearch插入数据 Python 2的多进程不能序列化类方法, 所以改为函数的形式. 直接上代码: #!/usr/bin/python # -*- coding:ut ...python操作Elasticsearch &lpar;一、例子&rpar;E lasticsearch是一款分布式搜索引擎,支持在...

weixin_39713805的博客 436
上一篇: 图解机器学习
下一篇: 使用Heapster和Splunk监控Kubernetes运行性能
刚是程序员
博客等级 码龄9年 47粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值