我有一个 Oracle 数据库,与许多数据库一样,它有一个包含传记信息的表。对此,我想以“自然”的方式按名称搜索。
该表有forename
和surname
字段,目前,我正在使用这样的东西:
select id, forename, surname
from mytable
where upper(forename) like '%JOHN%'
and upper(surname) like '%SMITH%';
这行得通,但它可能会很慢,因为该表上的索引显然不能解释前面的通配符。此外,用户通常会根据他们通过电话告诉他们的内容来搜索人——包括大量的非英文名字——所以最好也做一些语音分析。
因此,我一直在试验 Oracle Text:
create index forenameFTX on mytable(forename) indextype is ctxsys.context;
create index surnameFTX on mytable(surname) indextype is ctxsys.context;
select score(1)+score(2) relevance,
id,
forename,
surname
from mytable
where contains(forename,'!%john%',1) > 0
and contains(surname,'!%smith%',2) > 0
order by relevance desc;
这具有使用 Soundex 算法以及全文索引的优点,因此它应该更有效一些。(虽然,我的轶事结果表明它非常缓慢!)对此我唯一的担忧是:
首先,需要以某种有意义的方式刷新文本索引。使用
on commit
速度太慢,并且可能会干扰前端软件(我无法控制)与数据库的交互方式;所以需要一些思考...Oracle 返回的结果并不是很自然地排序的。我不太确定这个
score
功能。例如,我的开发数据显示“Jonathan Peter Jason Smith”在顶部——很好——但“Jane Margaret Simpson”与“John Terrance Smith”处于同一水平
我认为删除前面的通配符可能会在不降低结果的情况下提高性能,因为在现实生活中,您永远不会在名称中间搜索块。但是,否则,我对想法持开放态度……这种情况一定是实施得令人作呕!任何人都可以对我现在正在做/考虑的事情提出更好的方法吗?
谢谢 :)