【问题标题】:Fuzzy search doesn't find Márton when searching for Marton搜索 Marton 时,模糊搜索未找到 Márton
【发布时间】:2014-11-28 19:45:26
【问题描述】:

我有一个存储人员的 Oracle 数据库 表。例如:

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

我使用 Oracle 在 name 列上进行模糊搜索。问题是当我搜索 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;

是我建立的索引错误还是使用模糊搜索错误?

【问题讨论】:

标签: sql oracle


【解决方案1】:

我今天找到了解决问题的方法。 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 了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2020-03-15
    • 2014-08-20
    • 2011-10-28
    相关资源
    最近更新 更多