Fuzzy Search是HANA提供的模糊搜索功能,传统的sql语句只提供了like关键字的假模糊搜索(实际还是精确搜索)。下面分别从字符串类型,文本类型,日期类型来说明Fuzzy Search的使用。(HANA还支持中文语音情感分析等功能)
有下面一张表:
Fuzzy Search的用法如下所示:
Score()是对两个字符串进行比较,按照一些算法得到的分值,分数越高,表明两个字符串相似度越高。Fuzzy函数有两个参数,0.8是最小匹配分数,得分大于等于0.8的记录会返回,similarCalculationMode说明两个字符串用什么样的方式来计算相似度,默认是compare,下表说明了这个参数的取值及其影响:
similarCalculationMode |
wrong characters |
additional characters in search |
additional characters in table |
search |
high impact |
high impact |
low impact |
compare (default) |
moderate impact |
high impact |
high impact |
symmetricsearch |
high impact |
moderate impact |
moderate impact |
当采用文本类型进行FUZZYSEARCH时,文本会被分割成一个个的词;然后FUZZYSEARCH会在这些词之间一个个的进行比较。我们采用同样的例子,首先建立同样字段的表,当字段类型采用TEXT,然后插入同样的记录进行搜索:
CREATE COLUMN TABLE SEARCH_TEXT_TMP(
CONTENTTEXT
);
INSERT INTO SEARCH_TEXT_TMP VALUES('SAP DeutschlandAG & Co. KG');
SELECT SCORE(),*
FROM SEARCH_TEXT_TMP
WHERECONTAINS(CONTENT, 'SAP', FUZZY(0.2)) ;结果如下所示:
基于日期上的FUZZYSEARCH支持两种容错,日期类型的拼写错误和用户自定义的最大距离。
1. 拼写错误的得分计算
类似于是用编辑距离或者其他的字符串比较算法,时间比较算法也比较类似:
(1) 一个任意位置数据错误(例如2011-08-15代替2011-08-25)。这类错误会得到0.9分。
(2) 日期中一个部分(年、月、日)的两个数字颠倒位置(例如2001-01-12, 2010-10-12,或者2010-01-21代替2010-01-12)。这类错误会得到0.85分。
(3) 月和日期颠倒(例如2010-10-12代替2010-12-10)。这类错误会得到0.8分。
日期比较中,上述错误中仅容许有且只有一个。两个及以上的错误被认为是非相似的,得分为0.0。
我们创建一张日期类型的表:
CREATE TABLE SEARCH_DATE(
CONTENT DATE
);
然后插入如下几个数据:2000-01-11,2000-01-10,2000-01-01,2000-10-01,2000-10-02.
SELECT SCORE() AS score,TO_VARCHAR (CONTENT, 'YYYY-MM-DD')
FROM SEARCH_DATE
WHERE CONTAINS(CONTENT, '2000-01-10', FUZZY(0.8))
ORDER BY score DESC;
容许日期之间的最大距离可以用搜索选项“maxDateDistance”来设置。默认值为0,该选项被禁用。如果我们设置为5那么,搜索日期的前后五天都是有效的时间。
(1) 相同的日期得分1.0。
(2) 日期距离等于maxDateDistance的日期,得分为用户输入的fuzzySimilarity参数值,如下面的0.95。
(3) 位于'maxDateDistance'之内的日期并且出去相同的,得分为1-((1-fuzzySimilarity)/
maxDateDistance。
(4) 除此之外,其他的得分均为0.
例如我们向SEARCH_DATE表中插入2000-01-05到2000-01-15的日期。然后执行如下搜索:
SELECT SCORE() AS score,TO_VARCHAR (CONTENT, 'YYYY-MM-DD')
FROM SEARCH_DATE
WHERE CONTAINS(CONTENT, '2000-01-10', FUZZY(0.95, 'maxDateDistance=5'))
ORDER BY score DESC
该搜索返回了2000-01-05到2000-01-15的所有日期。如果一个日期同时满足拼写错误和最大距离,score()会返回得分最高的那个分数。
基于上面同样的数据,我们作下面的搜索:
SELECT SCORE() AS score,TO_VARCHAR (CONTENT, 'YYYY-MM-DD')
FROM SEARCH_DATE
WHERECONTAINS(CONTENT, '2000-01-10', FUZZY(0.8,'maxDateDistance=5'))
ORDER BY score DESC;
我们不能试图使用FUZZY(0)来返回所有结果。FUZZY(0)将会返回所有FUZZYSCORE大于0的记录。
TRUNCATE TABLE SEARCH_TEXT;
INSERT INTO SEARCH_TEXT VALUES('HANAGEEK');
INSERT INTO SEARCH_TEXT VALUES('SAP');
SELECT SCORE() AS SCORE,*
FROM SEARCH_TEXT
WHERECONTAINS(CONTENT,'HANAGEEK',FUZZY(0.0))
ORDER BY SCORE DESC;