gpt4 book ai didi

mysql - 如何在数据库中搜索文本片段

转载 作者:可可西里 更新时间:2023-11-01 06:38:57 27 4
gpt4 key购买 nike

是否有任何开源或商业工具允许数据库内容的文本片段索引并可以从 Java 查询?

问题的背景是一个包含数十万条记录的大型 MySQL 数据库表,其中包含几个 VARCHAR 列。在这些列中,人们想搜索内容的片段,因此全文索引(基于词边界)无济于事。

编辑 :[添加以明确为什么这些最初的建议不能解决问题:]

这就是为什么 MySQL 的内置全文索引不能完成这项工作,Lucene 或 Sphinx 也不能,所有这些都在答案中提出。我已经看过这两个,但据我所知,这些都是基于索引词,排除停用词并为真正的全文搜索做各种明智的事情。然而,这并不合适,因为我可能正在寻找像“oison”这样的搜索词,它必须与“Roisonic Street”和“Poison-Ivy”匹配。这里的主要区别在于搜索词只是 栏目内容片段 , 不需要由任何特殊字符或空格分隔。

编辑2 :[添加了更多背景信息:]
基于此实现的请求功能是在商品管理系统中对项目描述进行非常松散的搜索。用户通常不知道正确的项目编号,而只知道项目名称的一部分。不幸的是,这些描述的质量相当低,它们来自遗留系统,不能轻易更改。例如,如果人们正在寻找大锤,他们会输入“sledge”。使用基于单词/标记的索引,这不会找到存储为“大锤”的匹配项,但只有那些听“大锤”的匹配项。需要涵盖各种奇怪的差异,这使得基于 token 的方法不切实际。

目前我们唯一能做的就是 LIKE '%searchterm%'查询,有效地禁用任何索引使用并需要大量资源和时间。

理想情况下,任何此类工具都会创建一个索引,使我能够非常快速地获得此类查询的结果,以便我可以实现类似聚光灯的搜索,仅在用户选择时通过主键从 MySQL 表中检索“真实”数据结果记录。

如果可能,索引应该是可更新的(不需要完全重建),因为数据可能会发生变化并且应该可以立即被其他客户端搜索。

我很乐意得到建议和/或经验报告。

EDIT3:商业解决方案发现“正常工作”
尽管我对这个问题得到了很多很好的答案,但我想在这里指出,最终我们选择了一种名为“QuickFind”的商业产品,由一家名为“HMB Datentechnik”的德国公司制造和销售。请注意,我与他们没有任何关联,因为当我继续描述他们的产品可以做什么时,它可能看起来像那样。不幸的是他们的website看起来很糟糕,只有德国人,但产品本身真的很棒。我目前有他们的试用版——你必须联系他们,没有下载——我印象非常深刻。

由于没有完整的在线文档,我将尝试描述我目前的经历。

他们所做的是根据数据库内容构建自定义索引文件。他们可以通过 ODBC 进行集成,但据我所知,客户很少这样做。相反 - 这就是我们可能会做的 - 您从主数据库生成文本导出(如 CSV)并将其提供给他们的索引器。这允许您完全独立于实际的表结构(或任何 SQL 数据库);事实上,我们导出从几个表连接在一起的数据。索引可以稍后动态增量更新。

基于此,他们的服务器(仅 250kb 左右,作为控制台应用程序或 Windows 服务运行)在 TCP 端口上监听查询。该协议(protocol)是基于文本的,看起来有点“旧”,但它简单且有效。基本上,您只需传递要查询的可用索引和搜索词(片段),空格分隔。
有三种可用的输出格式,HTML/JavaScript 数组、XML 或 CSV。目前我正在为有点“过时”的有线协议(protocol)开发 Java 包装器。但结果非常好:我目前有一个包含大约 500.000 条记录的样本数据集,其中有 8 列索引,并且我的测试应用程序在编辑时每次击键时都会在所有 8 列中触发对 JTextField 内容的搜索,并且可以更新结果显示(JTable) 实时!无需转到数据最初来自的 MySQL 实例即可发生这种情况。根据您返回的列,您可以通过使用该行的主键查询 MySQL 来请求“原始”记录(当然需要包含在 QuickFind 索引中)。

索引大约是文本导出版本数据大小的 30-40%。索引主要受磁盘 I/O 速度的限制;我的 500.000 条记录需要大约一两分钟的时间来处理。

这很难描述,因为当我看到内部产品演示时,我什至觉得难以置信。他们提供了一个 1000 万行的地址数据库并搜索了姓名、地址和电话号码的片段,当点击“搜索”按钮时,结果在一秒钟内返回——所有这些都在笔记本上完成!据我所知,当调用中心座席只了解调用者姓名或地址的片段时,他们经常与 SAP 或 CRM 系统集成以缩短搜索时间。

所以无论如何,我可能不会更好地描述这一点。如果你需要这样的东西,你一定要去看看。 Google Translate在将他们的网站从德语翻译成英语方面做得相当不错,所以这可能是一个好的开始。

最佳答案

这可能不是您想听到的,因为我认为您正试图用 SQL 代码解决这个问题,但是 Lucene将是我的第一选择。您还可以使用其他工具建立相当聪明的排名和提升技术。 Lucene 是用 Java 编写的,因此它应该为您提供所需的接口(interface)。

如果您是 Microsoft 商店,您要查找的大部分内容都内置在 SQL Server 中,并且可以启用通配符,这将使您能够进行部分单词匹配。

在 Lucene 和 Lucene.Net 中,您可以使用 wildcard matches如果你喜欢。但是,不支持使用通配符作为搜索中的第一个符号。如果您希望能够使用第一个字符通配符,您可能需要自己实现某种基于 trie 的索引,因为在许多情况下,将术语集过滤为合理的类型是一项昂贵的操作全文搜索应用程序最常需要的索引,其中后缀提取通常更有值(value)。

您显然可以通过将 setAllowLeadingWildcard 设置为 true 来更改 Lucene 中的 Query Parser 实例以覆盖此规则。

我相当确定单词两端的通配符搜索本质上是低效的。跳过列表有时用于提高纯文本搜索的性能,但我认为您更有可能在 grep 之类的东西中找到类似的实现,而不是通用文本索引工具。

对于您所描述的一个单词可能出现在何处拼写为两个单词的问题,还有其他解决方案,反之亦然。例如,Lucene 支持模糊查询。可以通过提供基于某种贝叶斯机制提供建议的过滤器或通过索引技巧,即获取频繁变体的语料库并用这些术语填充索引来处理正字法和形态学变体。我什至看到将结构化数据中的知识填充到全文引擎中(例如,将城市名称和“酒店”一词添加到酒店表的记录中,以使“巴黎酒店”更有可能包含养老金记录-house Caisse des Dépôts。)虽然不是一个微不足道的问题,但它是可以管理的,而不会破坏基于单词的搜索的优势。

关于mysql - 如何在数据库中搜索文本片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1627689/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com