请教一个关键词检测问题.

2020-12-15 17:59:06 +08:00
 molika

某些用户会关注一些关键字 如:西瓜 牛奶 香蕉 等,大概如下结构:

{'key_1':[u1,u2,u3,u4]}
{'key_2':[u4]}
{'key_3':[u2,u3,u4]}

恩,其实就是一个 key 对应多个用户.

如果以用户角度来看,其实就是:

{u1:[key_1]}
{u2:[key_1,key_3]} ....

现在有大量文本需要检测是否包含上面所有的 key.如果包含 就取到对应的 key 与 id[ux] 这种数据应该怎么存储比较合适呢并检索? 如果有可用的工具 最好越轻越好.. key 大概 2w-5w 备注:文本大概 100 字以内

2692 次点击
所在节点    Python
25 条回复
TimePPT
2020-12-15 18:21:32 +08:00
需求不太明白,不过感觉可以试试 FlashText ?
https://github.com/vi3k6i5/flashtext/
kevinwan
2020-12-15 18:26:19 +08:00
go 的要不要?如果可以的话,https://github.com/tal-tech/go-zero
里面有,core/stringx 包里
err1y
2020-12-15 18:36:21 +08:00
用图数据库,比如 neo4j
jingous
2020-12-15 18:42:06 +08:00
怎么有一种倒排索引的感觉
wunonglin
2020-12-15 19:06:26 +08:00
@jingous #4 哈哈哈哈哈哈,好像就是倒排
fuxiuyin
2020-12-15 19:18:08 +08:00
问题拆分成两个,第一个是找到这些文本命中那些关键词,第二个是找到命中的关键词对应哪些用户。第一个可以用关键词建一个 AC 自动机做文本匹配,第二个可以存一个 kv 数据库。
molika
2020-12-15 19:21:34 +08:00
@jingous 是的 一种倒排索引 但是我想很轻量的实现. 想看看大家有木有好的思路和想法 学习一下~
molika
2020-12-15 19:23:10 +08:00
@TimePPT 我看下~感谢
molika
2020-12-15 19:23:26 +08:00
@err1y 还用不上这么高级的东西(逃
molika
2020-12-15 19:23:47 +08:00
@kevinwan 我了解下 go 的也可以哈哈 感谢
kevinwan
2020-12-15 23:09:35 +08:00
@molika 我们百万级 qps 的并发都是通过 go-zero 的关键词过滤库做的,既然愿意尝试 go 的,那你可以看看能否用上哈
lpts007
2020-12-16 07:39:44 +08:00
好像有一个 e 开头的库,跟 es 有关的,谁知道顺便告诉我一下
goinghugh
2020-12-16 09:52:57 +08:00
lucene?
MinQ
2020-12-16 10:01:22 +08:00
这种起个 redis,value 用 set 存,key 就是关键词?
molika
2020-12-16 10:16:16 +08:00
@MinQ 要在大量文本里面查找并确认每一个存在的 key
molika
2020-12-16 10:16:35 +08:00
@lpts007 我也想知道 es 太重了 跑不动
molika
2020-12-16 10:17:02 +08:00
@goinghugh 恩 目前在用这个了
molika
2020-12-16 10:17:35 +08:00
@fuxiuyin 收到~
laminux29
2020-12-16 10:27:52 +08:00
这种问题,建议按经济实力去考虑。

1.如果经济条件欠发达,建议用时间换成本的做法:

3 个表:用户表、关键词表、关键词与用户对应表。

每个表都不能有重复的,来节约存储空间与内存,但牺牲的是计算量、计算时间。



2.如果经济条件发达,玩法就完全不一样了,核心原则就变成了节约时间:

2.1 用户数据相关的 2 种表:

2.1.1 用户表:
可以重复的用户表。用户数据录入到这个表,但不从这个表取数据。

不可重复的用户表,数据是从上表,通过最终一致性 + 散列分布式 + 流式处理到该表里。数据取出也是从这个表取,这样子处理,取出速度最快。

2.2.2 用户-关键词表:
该表本质是用于节约时间,是一种冗余表。这种表也同上,做两款,一款拿来录入数据,允许重复;一款拿来高速取出数据,不允许数据重复。

2.2 关键词数据相关的表:
同与上面的用户数据表,一共 2 种:关键词表与冗余的关键词-用户表。做法也同上,每种表也做重复与不重复两套。


总结一下,以上一共 8 个表,为节约时间服务,也就是为高速取出数据服务,牺牲了存储空间与内存。

另外,如果存储用的是高级存储设备或做了软阵列或分布式副本提速,需要考虑数据录入速率与存储底层条带化结构( raid 0 )或分布式散列结构的关系,以及数据取出时与存储底层镜像化( raid 1 )或分布式副本化的关系。也就是在读写时,画个流程图,思考一下底层存取逻辑与读写性能的关系。
MinQ
2020-12-16 10:28:49 +08:00
@molika 这是两个任务,在大量文本里面查找并确认每一个存在的 key 是个全文搜索任务。如果待搜索全文不需要存储的话直接把字典加载到内存里,然后跑 AC 自动机?

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

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

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

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

© 2021 V2EX