我正在实现一个自动完成功能,允许用户输入部分文本,然后将其与表格中的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”,则由于其login
和email
列值,只有第一条记录匹配。等等。我还想返回按相似性排序的结果,其中第一个结果是“最接近的匹配”,依此类推结果(标准自动完成行为)。
我目前一直在尝试使用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
结果并不像我希望的那样准确,而且我已经看到了野外的自动填充功能,就像我希望我的工作方式一样,但不知道它们是如何实现的。后端。
有人能指出我正确的方向吗?
答案 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;