Oracle中的模糊文本搜索

时间:2014-08-12 07:54:06

标签: sql oracle fuzzy-search

我有一个大型Oracle数据库表,其中包含整个国家/地区的街道名称,其中包含600000多行。在我的应用程序中,我将地址字符串作为输入,并想检查此地址字符串的特定子字符串是否与表中的一个或多个街道名称匹配,以便我可以将该地址子字符串标记为街道的名称。 / p>

显然,这应该是一个模糊的文本匹配问题,我查询的子字符串与DB表中的街道名称完全匹配的可能性很小。所以应该有某种模糊文本匹配方法。我正在尝试阅读http://docs.oracle.com/cd/B28359_01/text.111/b28303/query.htm中的Oracle文档,其中解释了CONTAINS和CATSEARCH搜索运算符。但这些似乎用于更复杂的任务,例如在文档中搜索给定字符串的匹配项。我只是想为表的一列做这件事。

在这种情况下,您对我有什么建议?Oracle是否支持这种模糊文本匹配查询?

2 个答案:

答案 0 :(得分:8)

UTL_MATCH包含匹配字符串和比较字符串相似性的方法。该  编辑距离,也称为Levenshtein距离,可能是一个很好的起点。由于一个字符串是子字符串,因此可以帮助比较编辑距离  相对于字符串的大小。

--Addresses that are most similar to each substring.
select substring, address, edit_ratio
from
(
    --Rank edit ratios.
    select substring, address, edit_ratio
        ,dense_rank() over (partition by substring order by edit_ratio desc) edit_ratio_rank
    from
    (
        --Calculate edit ratio - edit distance relative to string sizes.
        select
            substring,
            address,
            (length(address) - UTL_MATCH.EDIT_DISTANCE(substring, address))/length(substring) edit_ratio
        from
        (
            --Fake addreses (from http://names.igopaygo.com/street/north_american_address)
            select '526 Burning Hill Big Beaver District of Columbia 20041'   address from dual union all
            select '5206 Hidden Rise Whitebead Michigan 48426'                address from dual union all
            select '2714 Noble Drive Milk River Michigan 48770'               address from dual union all
            select '8325 Grand Wagon Private Sleeping Buffalo Arkansas 72265' address from dual union all
            select '968 Iron Corner Wacker Arkansas 72793'                    address from dual
        ) addresses
        cross join
        (
            --Address substrings.
            select 'Michigan'           substring from dual union all
            select 'Not-So-Hidden Rise' substring from dual union all
            select '123 Fake Street'    substring from dual
        )
        order by substring, edit_ratio desc
    )
)
where edit_ratio_rank = 1
order by substring, address;

这些结果并不好,但希望这至少是一个很好的起点。它应该适用于任何语言。但是你仍然可能希望将它与一些语言或特定于语言环境的比较规则结合起来。

SUBSTRING          ADDRESS                                                  EDIT_RATIO
---------          -------                                                  ----------
123 Fake Street    526 Burning Hill Big Beaver District of Columbia 20041   0.5333
Michigan           2714 Noble Drive Milk River Michigan 48770               1
Michigan           5206 Hidden Rise Whitebead Michigan 48426                1
Not-So-Hidden Rise 5206 Hidden Rise Whitebead Michigan 48426                0.5

答案 1 :(得分:1)

您可以使用 Oracle 数据库中提供的SOUNDEX函数。 SOUNDEX计算文本字符串的数字签名。这可用于查找听起来相似的字符串,从而减少字符串比较的次数。

<强>编辑: 如果SOUNDEX不适合您的当地语言,您可以向 Google 询问语音签名或语音匹配功能,该功能效果更佳。每个新表条目必须评估此函数一次,每个查询一次评估一次。因此,它不需要驻留在 Oracle 中。

示例:提升土耳其语SOUNDEX here

要提高匹配质量,应在第一步统一街道名称拼写。这可以通过应用一组规则来完成:

简化示例规则:

  1. 将所有字符转换为小写
  2. 删除&#34; str。&#34;在名称的末尾
  3. 删除&#34; drv。&#34;在名称的末尾
  4. 删除&#34;地点&#34;在名称的末尾
  5. 删除&#34; ave。&#34;在名称的末尾
  6. 按字母顺序对多个单词排名
  7. 删除&#34;,&#34;和&#34;,&#34;&#34;,...
  8. 等辅助词