Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中字符串的模糊匹配_Java_String_Fuzzy Search - Fatal编程技术网

Java中字符串的模糊匹配

Java中字符串的模糊匹配,java,string,fuzzy-search,Java,String,Fuzzy Search,我有一个非常大的字符串列表存储在NoSQL数据库中。传入查询是一个字符串,我想检查列表中是否有该字符串。在精确匹配的情况下,这是非常简单的。NoSQL DB可能将该字符串作为主键,我将只检查是否有任何记录将该字符串作为主键。但我也需要检查模糊匹配 有一种方法可以遍历该列表中的每个字符串并检查输入字符串与列表中的字符串之间的Levenshtein距离,但这种方法将导致O(n)复杂性,并且列表的大小非常大(1000万),甚至可能会增加。这种方法将导致我的解决方案出现更高的延迟 有没有更好的方法来解决

我有一个非常大的字符串列表存储在NoSQL数据库中。传入查询是一个字符串,我想检查列表中是否有该字符串。在精确匹配的情况下,这是非常简单的。NoSQL DB可能将该字符串作为主键,我将只检查是否有任何记录将该字符串作为主键。但我也需要检查模糊匹配

有一种方法可以遍历该列表中的每个字符串并检查输入字符串与列表中的字符串之间的Levenshtein距离,但这种方法将导致O(n)复杂性,并且列表的大小非常大(1000万),甚至可能会增加。这种方法将导致我的解决方案出现更高的延迟


有没有更好的方法来解决这个问题?

首先,如果您正在进行搜索,那么您应该使用搜索引擎(ElasticSearch几乎是默认的)。他们很擅长这一点,而你不是在重新发明轮子

其次,您正在寻找的技术称为。与原始字符串一起,在数据库中保存一个规范化字符串。使用相同的机制规范化搜索查询。这样你会得到更好的搜索结果。显然,这是搜索引擎在引擎盖下使用的技术之一。

使用Solr(或Lucene)可能是适合您的解决方案

Lucene支持基于Levenshtein距离或编辑距离算法的模糊搜索。要进行模糊搜索,请在单个单词词尾使用波浪号“~”符号。例如,要搜索拼写与“roam”相似的术语,请使用模糊搜索:

roam~
此搜索将查找泡沫和漫游等术语

从Lucene 1.9开始,额外的(可选)参数可以指定所需的相似性。该值介于0和1之间,如果值接近1,则仅匹配相似度较高的术语。例如:

roam~0.8 

由于您发现的原因,模糊匹配非常复杂。由于性能原因,为搜索项与数据库项的每个组合计算距离度量是不切实际的

解决这个问题的方法通常是使用n-gram索引。这可以单独使用以给出结果,也可以作为一个过滤器来减少可能结果的大小,从而减少要计算的距离分数

所以基本上,如果你有一个单词“stack”,你可以把它分解成n个g(通常是三角图),比如“s”、“st”、“sta”、“ack”、“ck”、“k”。您可以根据数据库行对数据库中的数据进行索引。然后对输入执行相同的操作,并查找具有相同匹配n-gram的数据库行

这非常复杂,您最好的选择是使用现有的实现,如Lucene/Solr,它将为您完成n-gram的工作。我自己在使用专有解决方案时没有使用它,但有一个可能与此相关的stackoverflow问题:

一些数据库似乎实现了n-gram匹配。下面是一个指向Sybase页面的链接,该页面提供了一些关于该问题的讨论:


不幸的是,关于n-gram的讨论将是一篇很长的文章,我没有时间。可能在stackoverflow和其他网站上讨论过。我建议用谷歌搜索这个词并阅读它。

搜索模糊字符串总是很复杂的。它导致了高复杂性,我认为没有真正好的解决方案可以避免这种情况。在搜索之前是否可以更正模糊字符串?但是您使用哪种非SQL数据库呢。其中一些提供了模糊字符串的搜索功能。或者你应该尝试使用搜索引擎,比如为什么不使用语音算法,比如Soundex或Metaphone。你可以尝试一下。Apache commons文本库提供了一些例程来实现这一点,比如余弦距离,但听起来你至少想使用嵌入式Lucene来实现这一点。即使使用Lucene Levenshtein,距离搜索的成本也很高,尽管Lucene改进了这一点。标准方法是使用n-gram。更多细节见下面的答案。他想做一个Levenshtein距离,所以词干法在这方面没有帮助。更复杂的是,我听说他尝试过这种方法,但不是说这是一种要求。谢谢你的建议。我最初的方法是使用Levenshtein距离,但如果其他方法更好,我也愿意使用。对于原始方法,我需要解析完整的列表。我在想,如果这个列表非常大,我不想对每个查询都进行解析,那么它是否可以被优化。词干分析不能帮助返回带有一个字母错误的结果,比如
water/woter
@mishadoff true,但它比他现在的结果要好。请随意添加您自己更完整的答案只是一个小贴士:ElasticSearch和Solr的核心是Lucene@谢谢你的建议!我从评论中看到,Lucene提供了精确匹配和模糊匹配,Solr和Elastic搜索都是基于Lucene的。Solr或Elastic Search中是否也有超时功能,可以在固定时间后删除记录?另外,我希望延迟在中不是问题both@DevilAFAIK没有任何“固定时间后删除记录”功能,但您可以轻松地向文档中添加一个创建时间戳字段,并筛选早于指定日期时间的结果,或/或定期删除所有早于。。。