Oracle:多列“最近匹配”自动完成策略

时间:2012-05-17 14:23:01

标签: oracle autocomplete

我正在实现一个自动完成功能,允许用户输入部分文本,然后将其与表格中的4个不同列进行匹配。这是一个基本的例子:

+------------+-----------+--------+-----------------+
| first_name | last_name | login  | email           |
+------------+-----------+--------+-----------------+
| John       | Smith     | jsmith | jsmith@foo.bar  |
| Johnny     | Ringo     | ringo  | ringer@hmm.okay |
| Bob        | Jones     | bjones | j1234@xyz.abc   |
| Jane       | Doe       | doej   | doedoe@blah.umm |
+------------+-----------+--------+-----------------+

当用户输入“jo”时,我想匹配此表中的记录,其中这四列中的至少一列与模式“jo%”匹配。对于此示例,由于其first_name列值,只有前两个匹配。如果搜索是“js”,则由于其loginemail列值,只有第一条记录匹配。等等。我还想返回按相似性排序的结果,其中第一个结果是“最接近的匹配”,依此类推结果(标准自动完成行为)。

我目前一直在尝试使用UTL_MATCH和产生以下查询的代码来解决此问题:

SELECT first_name,
  last_name,
  login,
  email,
      (  utl_match.jaro_winkler_similarity(first_name, 'js')
       + utl_match.jaro_winkler_similarity(last_name, 'js')
       + utl_match.jaro_winkler_similarity(login, 'js')
       + utl_match.jaro_winkler_similarity(email, 'js')) similarity
FROM users
WHERE LOWER(first_name) LIKE LOWER('js%')
OR LOWER(last_name) LIKE LOWER('js%')
OR LOWER(login) LIKE LOWER('js%')
OR LOWER(email) LIKE LOWER('js%')
ORDER BY similarity DESC

结果并不像我希望的那样准确,而且我已经看到了野外的自动填充功能,就像我希望我的工作方式一样,但不知道它们是如何实现的。后端。

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

搜索总是很有趣。你已经开始了一个非常好的基本方法。我通常做的是创建一个通过触发器加载的辅助表。触发器从users表加载主键,第二列是“搜索”列。在您的示例中,每行将产生4行。确保以大写形式存储结果,因此您可以索引列,Oracle将使用索引,因为您坚持使用类似的语法。它需要一个额外的表,但是表可以通过触发器维护。

    create table searcher
    (
    user_id  number, --FK back to users
    search_column  varchar2(50) -- or whatever size column is appropriate
    );

    select u.first_name, u.last_name, u.login. u.email,
utl_match.jaro_winkler_similarity(search_column, 'js')
    from users u
    join
    searcher s
    on (u.user_id = s.user_id)
    where s.search_column like upper('js%')
    order by 5;