在搜索Marton时,模糊搜索没有找到Márton

时间:2014-11-26 09:00:30

标签: sql oracle

我有一个 Oracle数据库表来存储人员。 E.g:

|-------------|---------|
| Name        | Data    |
|-------------|---------|
| Marton      | XYZ     |
| Márton      | XYZ     |
|-------------|---------|

我在name列上使用Oracle进行模糊搜索。问题是,当我搜索Márton时,我得到2个条目(这很好),但是当我搜索Marton时,我只得到一个不是我期望的条目。

以下是我尝试做的完整示例:

CREATE TABLE persons  (
    NAME VARCHAR(256) NOT NULL,
    DATA VARCHAR(256) NOT NULL
);

INSERT INTO persons VALUES('Marton', '42');
INSERT INTO persons VALUES('Márton', '42');

begin
    --ctx_ddl.drop_preference('my_store');
    ctx_ddl.create_preference('my_store', 'MULTI_COLUMN_DATASTORE');
    ctx_ddl.set_attribute('my_store', 'columns', 'NAME');

    --ctx_ddl.drop_preference('my_lexer');
    ctx_ddl.create_preference('my_lexer', 'BASIC_LEXER');  
    ctx_ddl.set_attribute('my_lexer','index_stems','NONE');

    --ctx_ddl.drop_preference('my_wordlist');
    ctx_ddl.create_preference('my_wordlist', 'BASIC_WORDLIST'); 
    ctx_ddl.set_attribute('my_wordlist','fuzzy_match','GENERIC');
    ctx_ddl.set_attribute('my_wordlist','stemmer','NULL');
end;
/

--DROP INDEX MY_FUZZY_IDX;
CREATE INDEX MY_FUZZY_IDX ON persons(NAME) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS ('datastore my_store section group ctxsys.auto_section_group lexer my_lexer wordlist my_wordlist stoplist ctxsys.empty_stoplist');

-- Returns only 1 entry! Not OK! 
select * from persons where contains(NAME, '(fuzzy(Marton, 65, 100, W) within NAME)', 0) > 0;

-- Returns both entries! OK!
select * from persons where contains(NAME, '(fuzzy(Márton, 65, 100, W) within NAME)', 0) > 0;

我是否构建了错误的索引,或者我是否使用模糊搜索错误?

1 个答案:

答案 0 :(得分:0)

我今天找到了解决问题的方法。 BASIC_LEXER有一个名为base_letter的选项,默认为NO。如果您将其设置为YES,则Oracle会将所有字词转换为基本字母(因此á将变为a)并且模糊搜索会按预期工作。

CREATE TABLE persons  (
    NAME VARCHAR(256) NOT NULL,
    DATA VARCHAR(256) NOT NULL
);

INSERT INTO persons VALUES('Marton', '42');
INSERT INTO persons VALUES('Márton', '42');

begin
    --ctx_ddl.drop_preference('my_store');
    ctx_ddl.create_preference('my_store', 'MULTI_COLUMN_DATASTORE');
    ctx_ddl.set_attribute('my_store', 'columns', 'NAME');

    --ctx_ddl.drop_preference('my_lexer');
    ctx_ddl.create_preference('my_lexer', 'BASIC_LEXER');  
    ctx_ddl.set_attribute('my_lexer','index_stems','NONE');

    -- THE FIX!
    ctx_ddl.set_attribute('my_lexer','base_letter','YES'); 

    --ctx_ddl.drop_preference('my_wordlist');
    ctx_ddl.create_preference('my_wordlist', 'BASIC_WORDLIST'); 
    ctx_ddl.set_attribute('my_wordlist','fuzzy_match','GENERIC');
    ctx_ddl.set_attribute('my_wordlist','stemmer','NULL');
end;
/

--DROP INDEX MY_FUZZY_IDX;
CREATE INDEX MY_FUZZY_IDX ON persons(NAME) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS ('datastore my_store section group ctxsys.auto_section_group lexer my_lexer wordlist my_wordlist stoplist ctxsys.empty_stoplist');

-- Returns both entries! OK!
select * from persons where contains(NAME, '(fuzzy(Marton, 65, 100, W) within NAME)', 0) > 0;
select * from persons where contains(NAME, '(fuzzy(Márton, 65, 100, W) within NAME)', 0) > 0;

有关详情,请参阅https://web.stanford.edu/dept/itss/docs/oracle/10g/text.101/b10730/cdatadic.htm