Oracle Fuzzy Text Matching: Difference between revisions

From WickyWiki
Created page with "Category:Oracle Category:201111 == Oracle Text == Wanneer je door je je database wilt kunnen "Googelen" heeft Oracle een oplossing "Oracle Text" voor je (Oracle 10g). Co..."
 
m 1 revision
(No difference)

Revision as of 07:26, 5 July 2013

Oracle Text

Wanneer je door je je database wilt kunnen "Googelen" heeft Oracle een oplossing "Oracle Text" voor je (Oracle 10g). Configuratie en gebruik is echter vrij ingewikkeld maar dan heb je wel ook erg veel mogelijkheden, waarschijnlijk meer dan je zal gebruiken. Daarom worden op deze pagina een aantal andere mogelijkheden gegeven.

Meer info:

Like

Met _LIKE_ kan je wildcards gebruiken om textvelden te vergelijken. Hierin is '?' een enkel willekeurig karakter en '%' nul of meer willekeurige karakters:

select kolom 
  from tabel 
  where kolom like 'een?waarde%'
  ;
kolom
------
een waarde
een_waarde 123
een_waarde 12%
een%waarde ABC

Wanneer je bijvoorbeeld wilt zoeken op een '%' of een '?' kun je een escape karakter definiëren:

select kolom
  from tabel 
  where kolom like '%\%%' escape '\'
  ;
kolom
------
een_waarde 12%
een%waarde ABC

Soundex

Wat doe je als je twee test-waarden wilt vergelijken die niet _exact_ hetzelfde hoeven te zijn? Oracle heeft echter ook nog een functie *SOUNDEX* die een string omzet naar een klank-codering. Deze matching is erg grof maar bijzonder handig zijn als je niet _elke_ combinatie wilt zien:

select *
  from tabel 
  where soundex(kolom1) =  soundex(kolom2)
  ;

Package UTL_MATCH

Oracle 10g heeft een package UTL_MATCH met daarin een aantal functies waarmee een matching percentage berekend kan worden. In het volgende voorbeeld worden een aantal functies gebruikt om de teksten voor te bereiden, met een union query wordt een kleine testset gemaakt zonder dat er een tabel nodig is.

De volgende functies worden gebruikt:

select kolom1, kolom2
  , convert(Upper(Trim(kolom1)),'us7ascii')
  , convert(Upper(Trim(kolom2)),'us7ascii')
  , UTL_MATCH.JARO_WINKLER_SIMILARITY(convert(Upper(Trim(kolom1)),'us7ascii') , convert(Upper(Trim(kolom2)),'us7ascii')) as Winkler
  , UTL_MATCH.EDIT_DISTANCE_SIMILARITY(convert(Upper(Trim(kolom1)),'us7ascii'),convert(Upper(Trim(kolom2)),'us7ascii')) as Distance
  from ( 
    select 'Eindhoven' as kolom1, 'Veldhoven' as kolom2 from dual 
    union
    select 'Eindhoven', 'ëïñdhóvèn' from dual 
    union
    select 'Eindhoven ', 'EiNdHovEn' from dual 
    union
    select 'Eindhoven', 'Helmond' from dual 
  )
  order by Winkler desc
  ;

Met de volgende query kunnen we een 'beste' Winkler-match selecteren, door wel minimaal 95% te eisen voorkomen we ongewenste combinaties:

select * from (
  select kolom1, kolom2
    , UTL_MATCH.JARO_WINKLER_SIMILARITY(
          convert(Upper(Trim(kolom1)),'us7ascii')
        , convert(Upper(Trim(kolom2)),'us7ascii')) as Winkler
    from (
      select 'Eindhoven' as kolom1, 'Veldhoven' as kolom2 from dual
      union
      select 'Eindhoven', 'ëïñdhóvèn' from dual
      union
      select 'Eindhoven ', 'EiNdHovEn' from dual
      union
      select 'Eindhoven', 'Helmond' from dual
    )
    order by Winkler desc
  ) where rownum<=1 -- TOP N rows
    and Winkler>=95 -- minimum match %
;