Flink实时构建倒排索引与全文检索

Stella981
• 阅读 441

Flink实时构建倒排索引与全文检索

对于搜索引擎,大家不会感到陌生,我们每天都在用。

我们在百度、谷歌上搜索我们想要的信息。比如,在输入框里输入关键字查询后,会返回很多和关键字相关的内容。

或者在电商网站输入想要购买的商品名称后,就立即能查到我们想要购买的商品信息。

但是大家有没有思考过,为什么网站能快速检索到我们想要看到的信息?这里其实用到了倒排索引技术。

简单的介绍一下倒排索引

举个例子,我们小时候背诵过的古诗,当我们看到一首诗的题目时,可以很快速的背诵诗的内容。但是如果我们看到一句诗时,却很难快速说出诗的题目。

或者我们看到诗的上半句,一般会很轻松的背诵出诗的下半句。但是根据诗的下半句,很难快速想到诗的上半句。

这是因为,我们大脑存储的诗词,是通过正排索引的方式组织起来的,类似于关系型数据库一样,通过id很快能查到详细内容。但是要通过内容反查id,就不是那么容易了。

再比如,我们的电脑里有很多文件,我们能搜索到一个文件里有什么词,但是我们统计某个词在哪些文件里出现过,以及出现的次数,就不是那么容易了。

下面内容,用Flink实时构建倒排索引,实现一个全文检索的功能。

需求:有大量文本文件,需要构建索引。输入某个关键字,输出关键字在哪些文件里出现过,以及在文件里出现的次数。

思路:批量读取磁盘上的文件内容,将文件内容发送给kafka,Flink从kafka消费数据,将数据内容分词,记录每次词出现的词频和所在的文件名,然后通过Flink sql实时统计每个单词所在的文件,和在每个文件中出现的次数,写入到下游存储。

关键代码如下:

1、收集文件内容并发送给kafka

这是个很简单的程序,通过递归读取目录下的全部文件,将文件信息发送给kafka。

public static void main(String[] args) throws Exception {

2、Flink消费kafka的数据,并对原始数据做ETL转化。

flatMap算子中的操作是,将上报的数据特殊中的特殊字符过滤并封装成Word类发送给下游。

方便起见,这里采用关键字+文件名的hashCode作为一行数据的唯一id,后续根据这个id实时更新倒排索引。

public static void main(String[] args) throws Exception {

public class Word {

3、最关键的一步,构建倒排索引,将收集的数据封装成Word发送到下游算子后,下游算子通过Flink sql实时统计每个单词出现的次数以及所在的文件,并将数据实时更新到MySQL中,代码如下:

private static void buildIndexAndSink(StreamTableEnvironment tabEnv) {

通过上面代码,我们可以将目录下的所有文件,构建倒排索引。然后将索引信息写入MySQL,查到的效果如下,可以看到,某个词在哪些文件里出现过,以及出现的次数。

Flink实时构建倒排索引与全文检索

拓展:

我们是不是可以做个简易的搜索引擎呢?原理与上面的案例类似,需要把文件名替换成url。

本文分享自微信公众号 - OutOfMemoryError(backend_technology)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
添砖java的啾 添砖java的啾
2年前
distinct效率更高还是group by效率更高?
目录00结论01distinct的使用02groupby的使用03distinct和groupby原理04推荐groupby的原因00结论先说大致的结论(完整结论在文末):在语义相同,有索引的情况下groupby和distinct都能使用索引,效率相同。在语义相同,无索引的情况下:distinct效率高于groupby。原因是di
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
2年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这