如何在大量文本中高效的匹配出字符串?

2021-07-15 17:01:16 +08:00
 v2zero

我不是专业做技术的,因此会有很多技术盲区,碰到棘手问题也不知如何自行寻找解决方案,因此提问,感谢诸位。

需求背景是这样的:

在数百万的网页 html 源代码里面,寻找出包含某个特定字符串(或匹配某条正则)的网页,输出其 URL 信息。

由于是数据分析用途,需要很频繁的为了突发的需求而多次运行。

目前的解决方案是这样的:

数据存在 MongoDB 里面( zstd 压缩),匹配的时候使用 Python 直接遍历出所有网页,再通过 Python 内置的方法( in 条件或者 re )来进行判断。

如果仅使用 in 条件,目前每秒平均能匹配 4000 多个网页,百万的网页全部运行一次需要十多分钟,比较费力。此外,已经配置了阿里云 ECS 的对应容量下可选的最高速度的 SSD 。

尝试过的其它方案有:

使用 ElasticSearch 来建立全文索引。但发现在占用了大量额外硬盘空间的代价下,需要全量导出匹配结果时候的效率仍然很低下,或许是 ES 仅在匹配 top n 结果的时候才是高效的?又或只是我哪里没做对?

也尝试过 MongoDB 取消压缩,发现速度变更慢了,或许瓶颈是在硬盘 IO 不是在 CPU 上面?

3392 次点击
所在节点    Python
25 条回复
nicolaz
2021-07-16 09:34:22 +08:00
AC 自动机应该可以吧
好处是如果你有 N 个关键词需要匹配的话,
一次循环就能全部匹配出来
而不需要每个词都跑一遍
wangxn
2021-07-16 09:34:48 +08:00
认真想想,我上面的说法还是太 naive,肯定有高效的方法。不了解
mainjzb
2021-07-16 10:37:09 +08:00
为什么大多数的 C++ 的开源库都喜欢自己实现 string ? - 韦易笑的回答 - 知乎
https://www.zhihu.com/question/54664311/answer/140494146
love2020
2021-07-16 13:48:44 +08:00
前缀树,一楼的 flashtext 。或者 AC 自动机。
corningsun
2021-07-16 17:50:03 +08:00
@xy90321
同意,先对文档做分词,应该是有上限的。
ES 的倒排序索引很适合这个场景,分词方法需要根据你们需求定制。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/789745

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX