加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

基于Python语言的大数据搜索引擎

发布时间:2019-07-11 21:55:18 所属栏目:优化 来源:简单艾
导读:副标题#e# 搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (Bloom Filter) 第一步我们先要实现一个布隆过

上代码:

  1. class Splunk(object): 
  2.  def __init__(self): 
  3.  self.bf = Bloomfilter(64) 
  4.  self.terms = {} # Dictionary of term to set of events 
  5.  self.events = [] 
  6.  def add_event(self, event): 
  7.  """Adds an event to this object""" 
  8.  # Generate a unique ID for the event, and save it 
  9.  event_id = len(self.events) 
  10.  self.events.append(event) 
  11.  # Add each term to the bloomfilter, and track the event by each term 
  12.  for term in segments(event): 
  13.  self.bf.add_value(term) 
  14.  if term not in self.terms: 
  15.  self.terms[term] = set() 
  16.  self.terms[term].add(event_id) 
  17.  def search(self, term): 
  18.  """Search for a single term, and yield all the events that contain it""" 
  19.  # In Splunk this runs in O(1), and is likely to be in filesystem cache (memory) 
  20.  if not self.bf.might_contain(term): 
  21.  return 
  22.  # In Splunk this probably runs in O(log N) where N is the number of terms in the tsidx 
  23.  if term not in self.terms: 
  24.  return 
  25.  for event_id in sorted(self.terms[term]): 
  26.  yield self.events[event_id] 
  • Splunk代表一个拥有搜索功能的索引集合
  • 每一个集合中包含一个布隆过滤器,一个倒排词表(字典),和一个存储所有事件的数组
  • 当一个事件被加入到索引的时候,会做以下的逻辑
  • 为每一个事件生成一个unqie id,这里就是序号
  • 对事件进行分词,把每一个词加入到倒排词表,也就是每一个词对应的事件的id的映射结构,注意,一个词可能对应多个事件,所以倒排表的的值是一个Set。倒排表是绝大部分搜索引擎的核心功能。
  • 当一个词被搜索的时候,会做以下的逻辑
  • 检查布隆过滤器,如果为假,直接返回
  • 检查词表,如果被搜索单词不在词表中,直接返回
  • 在倒排表中找到所有对应的事件id,然后返回事件的内容

我们运行下看看把:

  1. s = Splunk() 
  2. s.add_event('src_ip = 1.2.3.4') 
  3. s.add_event('src_ip = 5.6.7.8') 
  4. s.add_event('dst_ip = 1.2.3.4') 
  5. for event in s.search('1.2.3.4'): 
  6.  print event 
  7. print '-' 
  8. for event in s.search('src_ip'): 
  9.  print event 
  10. print '-' 
  11. for event in s.search('ip'): 
  12.  print event 
  13. src_ip = 1.2.3.4 
  14. dst_ip = 1.2.3.4 
  15. src_ip = 1.2.3.4 
  16. src_ip = 5.6.7.8 
  17. src_ip = 1.2.3.4 
  18. src_ip = 5.6.7.8 
  19. dst_ip = 1.2.3.4 

是不是很赞!

更复杂的搜索

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

上代码:

  1. class SplunkM(object): 
  2.  def __init__(self): 
  3.  self.bf = Bloomfilter(64) 
  4.  self.terms = {} # Dictionary of term to set of events 
  5.  self.events = [] 
  6.  def add_event(self, event): 
  7.  """Adds an event to this object""" 
  8.  # Generate a unique ID for the event, and save it 
  9.  event_id = len(self.events) 
  10.  self.events.append(event) 
  11.  # Add each term to the bloomfilter, and track the event by each term 
  12.  for term in segments(event): 
  13.  self.bf.add_value(term) 
  14.  if term not in self.terms: 
  15.  self.terms[term] = set() 
  16.  self.terms[term].add(event_id) 
  17.  def search_all(self, terms): 
  18.  """Search for an AND of all terms""" 
  19.  # Start with the universe of all events... 
  20.  results = set(range(len(self.events))) 
  21.  for term in terms: 
  22.  # If a term isn't present at all then we can stop looking 
  23.  if not self.bf.might_contain(term): 
  24.  return 
  25.  if term not in self.terms: 
  26.  return 
  27.  # Drop events that don't match from our results 
  28.  results = results.intersection(self.terms[term]) 
  29.  for event_id in sorted(results): 
  30.  yield self.events[event_id] 
  31.  def search_any(self, terms): 
  32.  """Search for an OR of all terms""" 
  33.  results = set() 
  34.  for term in terms: 
  35.  # If a term isn't present, we skip it, but don't stop 
  36.  if not self.bf.might_contain(term): 
  37.  continue 
  38.  if term not in self.terms: 
  39.  continue 
  40.  # Add these events to our results 
  41.  results = results.union(self.terms[term]) 
  42.  for event_id in sorted(results): 
  43.  yield self.events[event_id] 

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

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读