网易首页 > 网易号 > 正文 申请入驻

做代码搜索真的太难了!

0
分享至


Val Town 是工程师 Tom MacWright 开发的一个用于编写和部署 TypeScript 的社交网站。近日,Tom MacWright 想在网站上增加一个“代码搜索”的功能,然而,随着尝试的深入,他发现,一切远没有想象中那么容易,尤其是在不雇佣一个专门负责“搜索团队”的情况下,实现大规模搜索代码是很困难的。以下是他的一些经验分享。

原文:https://blog.val.town/blog/search-notes/

作者 | Tom MacWright

责编 | 苏宓

出品 | CSDN(ID:CSDNnews)

以下为译文:

Val Town 网站的搜索功能不是很好。目前,它是基于 Postgres ILIKE 功能构建的,只执行子串搜索:如果代码中有搜索词,就会出现在搜索结果中。这几乎不涉及排名,而且对多词查询的支持也很差。对于 Val Town 而言,更好的搜索是我们最需要的功能之一。

我正在努力改进这一点,但我们还没有找到适合我们需求的解决方案。以下是我们的一些研究笔记。目前我们了解到的情况是:

  • 主流搜索解决方案是针对自然语言而非代码设计的。

  • 有代码搜索需求的大公司花费了大量时间和金钱来构建自己的定制解决方案。

  • 我们已经有了大量数据,需要一个能很好扩展的解决方案。

  • 使用单独的搜索服务而不是数据库扩展所涉及的基础设施和复杂性权衡非常重要。


代码搜索与自然语言搜索

行业中现成搜索解决方案的一个常见问题是,它们是针对英语和其他自然语言设计的。例如,在通常的 FTS(Full Text Search)设置中,默认情况下会使用以下一些算法:

  • 删除停顿词:在索引文本之前,会从文本中删除“the”和“it”等词,因为它们太常见了,会给性能带来更多问题,得不偿失。

  • 词干提取:这主要是反转连接词,在将“running”这样的词添加到索引之前将其转化为“run”,并对搜索查询进行同样的处理,这样你就可以搜索“runs”,并得到包含“running”一词的文档的搜索结果。

  • 词形还原:有些搜索索引甚至可以用同义词替代更常见的词,这样,搜索 “excellent”就可以得到包含“great”的文档结果。

总而言之,这意味着从你存储在索引中的文档向量与文档完全不一样:


select * from to_tsvector('english', 'I am writing this example sentence');--- 'exampl':5 'sentenc':6 'write':3

所有这些规则的问题在于它们会对代码造成严重破坏。在 TypeScript 中,“the”并不是一个停止词:它是一个有效的变量名,你可能想搜索它。单词边界不一样,对函数名进行词干处理没有太大意义。


select * from to_tsvector('english','function stringifyNumber(a: number): string { return a.toString() }');-- 'a.tostring':7 'function':1 'number':4 'return':6 'string':5 'stringifynumb':2

这是一个相当糟糕的索引:它包含了一些本应是停止词的单词,如 function,而且不会将 a.toString() 分割成两个词块,因为.不是默认的词边界。


全文搜索

Postgres 有一个全文搜索的扩展(https://www.postgresql.org/docs/current/textsearch.html),我们的托管提供商Render 支持该扩展。我在以前的项目中使用过 FTS(Full Text Search),对于某些规模的项目,它的效果非常好。你可以尝试用 Postgres 来处理所有事情,老实说,到目前为止,我们一直在使用 Postgres。这是一项非常棒的技术,有很好的文档,我们的托管提供商也提供了很好的支持。

如果我们能使用 Postgres,我们就会使用:对于一个小团队来说,保持基础设施尽可能简单是至关重要的。

不过,我之前使用 FTS 的项目都遇到了性能问题,难以扩展--Observable 最终迁移到了 Elasticsearch。我们有大量的 vals,正在测试单节点 Postgres 集群的极限。很难找到使用 FTS 进行代码搜索的记录,不过可能有人在悄悄地使用它取得了成功。我想避免将其作为第一选择,而是将其放在我的后备选项中。


pg_trgrm

我们作为 v2 搜索算法软启动的解决方案是基于 pg_trgrm,它在 Postgres 中实现了 trigram 搜索。代码搜索似乎确实可以通过 trigram(三元组)获得成功:

  • Russ Cox(Go 语言创建者之一)在 2012 年发表的一篇著名文章讲述了 Google 代码搜索如何使用 trigram 索引和特殊的正则表达式实现在技术上取得成功的故事(https://swtch.com/~rsc/regexp/regexp4.html)。

  • GitHub 的新搜索系统也使用了 trigram 代码搜索,此外还有很多我都很羡慕的技术(https://github.blog/2023-02-06-the-technology-behind-githubs-new-code-search/)。

  • Sourcegraph 也从 Google 继承了基于 trigram 的搜索工具(https://github.com/sourcegraph/zoekt)。

Stephen Gutekanst(Sourcegraph CTO)关于在 Postgres 本地为版本库建立索引的系列博文为我们使用 Postgrespg_trgrm方法提供了大量信息(https://devlog.hexops.com/2021/postgres-regex-search-over-10000-github-repositories/)。我们用 gin_trgm_ops 在包含搜索文本的列上创建了一个 GIN 索引(https://www.postgresql.org/docs/current/gin.html)。

目前得出的结论是,这对于 regex 搜索来说是一个很好的解决方案,但我们并不是在进行 regex 搜索:大多数搜索都比较自由。我们使用 word_ similarity 进行搜索排名,但很难哄骗算法给我们一个合理的排序。


选择范围


有一些专门针对代码的工具,但大多数都是闭源的:GitHub 的搜索功能非常出色,但显然是一个拥有实时预算的专业团队的杰作。

  • Sourcegraph 维护的 Zoekt(https://github.com/google/zoekt)分支非常酷,但却非常小众,而且需要大量新的基础设施投入。

  • Elasticsearch (https://github.com/elastic/elasticsearch)可能是这个问题最终不可避免的解决方案。它没有代码特定的处理方式,但可以以几乎无限的方式进行定制。我们开始学习 Java 内存调优,并为我们的应用程序引入第一个持久磁盘存储,同时为我们的数据提供额外的真实来源,我们并不感到兴奋。也许我们可以使用 Elasticsearch Cloud 来避免维护开销。

  • Meilisearch(https://github.com/meilisearch/meilisearch)似乎是一个很有前途的 ES 替代方案,具有 Rust 的光芒,但他们似乎更强调延迟而非可扩展性,而且我们不确定基础设施的投入是否会更低。

  • ParadeDB(https://www.paradedb.com/)承诺会像 Elasticsearch 一样,但“只是 Postgres”,这非常吸引人,但我们还不能在 Render 中使用他们的扩展。


总结

总之,我们还在努力中。搜索代码而不是英文,难度会更高一些。对于一个小团队来说,我们的目标是保持基础架构简单、开发环境易于设置、数据存放在同一个地方,因此我们尽量小心谨慎,避免使用需要不断维护的东西。大多数大中型公司都有一个搜索“团队”,而不仅仅是一个搜索服务,这是有原因的。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
素颜的陈丽君并没有那么好看

素颜的陈丽君并没有那么好看

娱乐八卦木木子
2024-04-30 13:22:37
卡塔尔18艘LNG船大单,中国拿下!韩媒破防:谁也别想超越韩国

卡塔尔18艘LNG船大单,中国拿下!韩媒破防:谁也别想超越韩国

兵国大事
2024-04-30 15:30:41
大厂忙着踢皮球的时候也请看看脚下的人

大厂忙着踢皮球的时候也请看看脚下的人

关尔东
2024-04-29 00:13:21
“詹库杜”的时代落幕了?下个赛季,他们会更惨!

“詹库杜”的时代落幕了?下个赛季,他们会更惨!

西北望体育
2024-04-30 22:10:35
重庆好色院长包养20名情妇,案发后,竟因一本日记被判十二年

重庆好色院长包养20名情妇,案发后,竟因一本日记被判十二年

朝暮书屋
2024-04-24 16:57:00
张朝阳:游戏把陈天桥从一个普通人变成中国首富,丁磊一直很勤奋|张朝阳眼中的中国互联网30年(14)

张朝阳:游戏把陈天桥从一个普通人变成中国首富,丁磊一直很勤奋|张朝阳眼中的中国互联网30年(14)

搜狐科技
2024-04-30 19:08:58
最可怕的是,底层老百姓收入不涨,全民人均收入却节节攀升

最可怕的是,底层老百姓收入不涨,全民人均收入却节节攀升

鹏飞深文
2024-04-28 10:50:15
赵丽颖凭一己之力带动一座城的发展,得到官媒认证,就是说好优秀

赵丽颖凭一己之力带动一座城的发展,得到官媒认证,就是说好优秀

阿芒娱乐说
2024-04-30 22:44:48
知名女星突然宣布:离婚!

知名女星突然宣布:离婚!

深圳晚报
2024-04-29 21:42:21
13年前,向美国捐赠7000万的广东富豪,最终下场令人唏嘘不已!

13年前,向美国捐赠7000万的广东富豪,最终下场令人唏嘘不已!

华庭讲美食
2024-04-29 19:59:24
独行侠负于快船,欧文再说大实话,没有伦纳德他们是不一样的球员

独行侠负于快船,欧文再说大实话,没有伦纳德他们是不一样的球员

奕辰说球
2024-04-30 11:32:21
窝囊1败,中超大战:10人国安苦战天津,奇兵1脚致胜,3连胜升第3

窝囊1败,中超大战:10人国安苦战天津,奇兵1脚致胜,3连胜升第3

话体坛
2024-04-30 22:06:03
老友再聚:郭冬临亲述与江中14年的那些事儿

老友再聚:郭冬临亲述与江中14年的那些事儿

8字路口
2021-09-27 21:55:36
24岁小伙约45岁大妈开房,偷拍整个过程,大妈:一辈子都会有阴影

24岁小伙约45岁大妈开房,偷拍整个过程,大妈:一辈子都会有阴影

青史录
2023-09-19 19:03:40
穿Prada打网球的李娜,这简直又美又飒啊!

穿Prada打网球的李娜,这简直又美又飒啊!

娱乐圈酸柠檬
2024-04-30 16:38:57
华为一季度营收1785亿,净利润增长564%

华为一季度营收1785亿,净利润增长564%

观察者网
2024-04-30 18:38:09
凌晨4点,中国移动这家营业厅就有人排队办业务,顾客:跑了6次都没办上,还有人雇人排队

凌晨4点,中国移动这家营业厅就有人排队办业务,顾客:跑了6次都没办上,还有人雇人排队

每日经济新闻
2024-04-30 12:47:17
救援者讲述问界m7追尾细节:车门确实打不开,还听到了爆炸声

救援者讲述问界m7追尾细节:车门确实打不开,还听到了爆炸声

映射生活的身影
2024-04-30 21:50:36
生肖蛇人,请做好准备!家庭将发生人员调动,劝你最好看一眼!

生肖蛇人,请做好准备!家庭将发生人员调动,劝你最好看一眼!

牛锅巴小钒
2024-04-30 17:59:28
红酒大盗上演“调虎离山”戏码,价值20万元珍品失窃

红酒大盗上演“调虎离山”戏码,价值20万元珍品失窃

周到上海
2024-04-30 16:40:06
2024-04-30 23:36:49
CSDN
CSDN
成就一亿技术人
24612文章数 241796关注度
往期回顾 全部

科技要闻

华为一季度营收1784.5亿 净利196.5亿

头条要闻

外交部回应"马克龙和冯德莱恩将同中国元首在法会面"

头条要闻

外交部回应"马克龙和冯德莱恩将同中国元首在法会面"

体育要闻

穆雷,绝杀了一个时代

娱乐要闻

黄子韬被曝求婚徐艺洋 大量亲密照曝光

财经要闻

中共中央政治局:要灵活运用利率和存款准备金率等工具

汽车要闻

越野老炮最爱 哈弗新H9新增2.4T柴油机

态度原创

亲子
旅游
时尚
家居
健康

亲子要闻

福利!好多大牌好物在这里真便宜!

旅游要闻

五一大雨,浇灭了多少旅游城市的心气?

岁月不败美人,姐姐们的50岁也太好看了

家居要闻

心之所栖 黑白灰色系打造设计专属感

春天野菜不知不识莫乱吃

无障碍浏览 进入关怀版