Oracle
 sql >> Base de données >  >> RDS >> Oracle

Recherche de texte Oracle sur plusieurs tables et jointures

Je résous généralement les recherches en texte intégral sur plusieurs colonnes sur différentes tables en matérialisant une vue XML structurée de celles-ci, puis en créant l'index sur l'ensemble du XML.

Cette solution est générique et vous donne également une liberté de recherche :la vue entière ou seulement un sous-chemin. L'inconvénient est de gérer le rafraîchissement d'un MV qui ne peut généralement pas être rafraîchi rapidement; mais la mise à jour de l'index de texte intégral n'est généralement pas non plus en temps réel, vous pouvez donc simplement la planifier.

-- Crating the view
CREATE MATERIALIZED VIEW fulltext_helper
NOLOGGING
BUILD DEFERRED
REFRESH COMPLETE ON DEMAND
AS
SELECT 
   a.dob, -- we don't need to fulltext on him
   XMLELEMENT(helper,
     XMLFOREST(a.emp_no AS emp_no, 
              a.dept_no AS dept_no, 
              b.emp_name AS emp_name)
   ) AS indexme
FROM v_depts a 
LEFT OUTER JOIN employee_details b
ON (a.emp_no = b.emp_no);

-- Creating the index
BEGIN
    ctx_ddl.create_preference('fulltext_helper_lexer', 'BASIC_LEXER');
    ctx_ddl.create_preference('fulltext_helper_filter', 'NULL_FILTER');
END;
/
CREATE INDEX fulltext_helper_index ON fulltext_helper (indexme)
INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS (
    'DATASTORE CTXSYS.DIRECT_DATASTORE
     LEXER fulltext_helper_lexer
     FILTER fulltext_helper_filter');

-- Searching the whole data
SELECT * FROM fulltext_helper
WHERE contains(indexme, '{abc} INPATH (/helper)') > 0;

-- Searching only on "empno"
SELECT * FROM fulltext_helper
WHERE contains(indexme, '{abc} INPATH (/helper/emp_no)') > 0;