什么算法(思路) 能 快速的查找(搜索、索引) 包含 关键词的文档?

发布于 2021-11-28 19:22:41 字数 1091 浏览 723 评论 26

比如 有一个 对象 有 id,name  字段,然后 有一个 关键词 字段 words


比如 就叫 疾病

{
  id : 1,
  name : "脑梗死",
  words : ["脑动脉供血不足","头晕","脑供血不足","头痛","咳嗽"]
  
  .....
}
{
  id : 2,
  name : "高血压",
  words : ["偶感头晕","头晕","反复头晕","乏力","发作性头晕","头痛"]
  
  .....
}




....


类似的。。。..




要查询的词语为:


    头晕;头痛;咳嗽






现在想 查询 的是: 完全包含 这组词语,但 不需要完全匹配, 顺序 也不需要 相同。



通常  数据库的模糊查询,或者 支持 数组查询  的数据库 查询 就行了.




可是 如果 需要 查询的 词组 有 很多,比如 1000万个,那从 数据库查询 效率就太低了。


假设 被查询的 疾病 不是特别多,可以 加载到内存,那应该 怎么高效的查询呢?




比如 我自己想 :
     可以把 所有疾病 的关键词 拆分开 放入 键值对的形式 放入到 Map中:key 是 关键词,value 是 该疾病(一个疾病 会有多个key,一个 key 也 会对应 多个 疾病),
这样 需要 查询词组的时候 直接 用 该词组的的 每个 词语,从map中 按照 key  查询 ,java里 能直接 map.get(key),拿到包含其中一个词语的文章,这样就能过滤掉 很多。。。。。
然后呢。。。



(暂时不考虑语义解析,不考虑 分词,所有词语 以 特殊符号 拆分即可。)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(26

伪装你 2021-12-01 19:39:16

试试 Solr

清欢 2021-12-01 19:39:16

。。。谢谢

看透却不说透 2021-12-01 19:39:15

...以后会学习的..谢谢

居里长安 2021-12-01 19:39:10

另外还可以试试SQLite,这个文件型数据库也是支持全文检索的,读速度应该是非常非常快的,管理工具可以用SQLiteStudio2和3,可以考虑把文件放到内存/dev/shm/app/data.db3提供查询服务,速度快得肯定飞起!

输什么也不输骨气 2021-12-01 19:39:10

补充说明一下,因为你的用户输入,以及words字段的内容,分词都是手工确定的,所以并不需要分词功能,而且因为手工分词,全文检索的准确度也会更高.FullText索引查询速度也远比LIKE模糊搜索快.

北笙凉宸 2021-12-01 19:39:10

用神经网络   关键词提取 然后使用皮尔逊系数去处理  使用全文检索 把这几个维度合并到一块 排序

躲猫猫 2021-12-01 19:39:09

谢谢,在程序实现不了的情况下 会考虑你说的数据库的方式的。

成熟的代价 2021-12-01 19:39:08

嗯。。。 上面我的回复。。。

坚持沉默 2021-12-01 19:39:08

引用来自“CoCo丶Hu”的评论

倒排索引

丢了幸福的猪 2021-12-01 19:39:08

据说MySQL的FIND_IN_SET(str,strlist)性能比LIKE模糊查询好点,可以试试:

SELECT * FROM `sickness`

WHERE FIND_IN_SET('头晕', `words`)

   OR FIND_IN_SET('头痛', `words`)

   OR FIND_IN_SET('咳嗽', `words`);

其中words字段中内容以逗号隔开:

脑动脉供血不足,头晕,脑供血不足,头痛,咳嗽

不过还是推荐用MySQL-5.6.4后InnoDB的FULLTEXT全文索引,这个是支持中文的.

my.cnf的[mysqld]的innodb_ft_min_token_size默认是3,因为你这里最小单词长度是两个字,所以应该设为2或者1.

[mysqld]

innodb_ft_min_token_size=2

CREATE TABLE `sickness` (

    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

    `name` varchar(200) NOT NULL DEFAULT '',

    `words` text,

    PRIMARY KEY (`id`),

    FULLTEXT (`words`)

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

INSERT INTO `sickness`(`name`, `words`)

VALUES ('脑梗死', '脑动脉供血不足 头晕 脑供血不足 头痛 咳嗽');

INSERT INTO `sickness`(`name`, `words`)

VALUES ('高血压', '偶感头晕 头晕 反复头晕 乏力 发作性头晕 头痛');

SELECT * FROM sickness WHERE MATCH(`words`) AGAINST('头晕 头痛 咳嗽');


冷默言语 2021-12-01 19:39:07

回复
...

不再见 2021-12-01 19:39:06

回复
不是,我意思是 我回复的 使用倒排索引 查询一次 得到 一批结果以后呢?如果不想对初步查询出来的的结果一条条的比对的话,有什么好办法吗?

奢华的一滴泪 2021-12-01 19:39:05

回复
因为 我想的倒排索引的 形式 是: { A1:文档A ; A2:文档A ; A1:文档B ; } 如果 每个词语都是单个的词语的话,那么 不能直接把结果 查出来的 ,得进一步处理,对吧?

怎言笑 2021-12-01 19:39:01

回复
{ A1:文档A ; A2:文档A ; A1:文档B ; } 变成{ A1:[文档A,文档B] ; A2:[文档A] ; }生成Map<Key,List>的形式

妖妓 2021-12-01 19:38:44

倒排索引

虐人心 2021-12-01 19:38:42

这不就是找3个(A,B,C)3个文档中的共同文档么?

彼岸花ソ最美的依靠 2021-12-01 19:38:29

引用来自“Altman”的评论


words分词做反向索引,然后对输入词做分词,然后去查词的文档序号,如果需要模糊查询需要做词/词意的相似性分析,然后慢慢就做成搜索引擎了

归途 2021-12-01 19:38:14

嗯。。。我更希望用程序的方式 实现。。不过 不行 的话 也考虑用这种方式吧。

离去的眼神 2021-12-01 19:35:42

mysql 是支持全文搜索的,不过对中文的支持不行

IK切词后,转拼音,然后把拼音存数据库,使用全文搜索就可以了

字段用fulltext,表需要用MyISAM

还有此方案实现容易,但是几乎没有可以优化和提升的余地

ORACLE好像也有类似的全文检索

牵你的手,一向走下去 2021-12-01 19:33:43

没想到这个需求 最后 是搜索引擎的方向。。。

倚栏听风 2021-12-01 19:30:16


words分词做反向索引,然后对输入词做分词,然后去查词的文档序号,如果需要模糊查询需要做词/词意的相似性分析,然后慢慢就做成搜索引擎了

凌乱心跳 2021-12-01 19:18:13

这就算搜索引擎了?。。。需求确实 有些像。。

凡尘雨 2021-12-01 19:12:20

搜索引擎是个大坑,慢慢填

尐偏执 2021-12-01 17:59:53

其实我想问的 就是 “头痛”和“咳嗽” 当各自 查询到结果以后怎么办。。。也就是 你说的并集,那也就是说 最后 用 id 去重即可了。。谢谢。。

小瓶盖 2021-12-01 17:37:17

。。。不是去重,是取交集。。。谢谢了,也谢谢其他各位的热心帮忙。。

奈何桥上唱咆哮 2021-11-30 17:27:54

文档A 这个地方 不是真的放整个文档,只是一个标志,代表文档A,接着你就继续计算就是的啊。有2个文档A:["头晕","头痛"] B:["头痛","咳嗽"],A,B 肯定要持久化的,这是相对于DB而言就是A: id=10001,content=["头晕","头痛"] B:id=10002,content=["头痛","咳嗽"],而你的倒排索引就是:{"头晕":[10001,],"头痛":[10001,10002],"咳嗽":[10002]}。当你要取"头痛","咳嗽"时候,先获取:"头痛":[10001,10002]->T1,然后"咳嗽":[10002]->T2。然后计算并集就可以了啊。这样应该是够了的。如果觉得大数据计算很麻烦,参考BitMap的用法。原来的结构变成Map<Key,BitMap>这样的

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文