Intégration XML à DB2.


OmniFind V1R2/V1R3


Le serveur OmniFind est fourni avec la version 7 de IBM i. Il permet une indexation des champs texte, texte enrichi (format .doc ou .pdf, par exemple) et enfin, avec cette nouvelle version 1.2, les champs de type XML.

 

OmniFind apporte :

 

Ce produit s'installe par RSTLICPGM 5733OMF, les options 30,33 et 39 de SS1 et java (JV1) sont des pré-requis.


L'installation doit vous créer un serveur de texte avec l'ID n° 1 (cela créé un répertoire /QOpenSys/QIBM/ProdData/TextSearch/server1)

La requête suivante donne la liste des serveurs :
   SELECT SERVERID,SERVERPORT,SERVERSTATUS,SERVERPATH FROM QSYS2.SYSTEXTSERVERS
   (ServerStatus à 0 indique un serveur actif, 1 inactif)

Ainsi que System i navigator

 

le serveur se démarre avec cette même interface ou IBM Navigator Director




ou avec les procédures cataloguées suivantes

 

Indexation

Vous pouvez créer un index OmniFind sur les types de donnée suivants :

les données peuvent être stockées en texte simple, HTML, XML, ou un format enrichi. Elles seront transformées en UNICODE 1208 avant d'être indexées, donc pas de job en CCSID(65535).Ce ne sont pas des index traditionnels DB2 (pas d'objet, donc pas de SAVOBJ) , ils ne sont pas maintenus temps réel et n'ont d'existence que dans le cadre du serveur OmniFind.


Les index sont enregistrés dans SYSTXTINDX de QSYS2, trois triggers sont ajoutés à la table indexée qui stockent les mises à jour dans une table temporaire, dite table de transfert, crée elle aussi à cette occasion (toujours dans QSYS2).

Création d'un Index


CALL SYSPROCS.SYSTS_CREATE

Paramètres

(les valeurs par défaut des options sont stockées dans SYSTEXTDEFAULTS)

Exemple :

CALL SYSPROC.SYSTS_CREATE('BDVIN1', 'PRODUCTEURS_IX',  'BDVIN1.PRODUCTEURS(PR_AVIS)', 
 'CCSID 1208 LANGUAGE fr_FR FORMAT TEXT UPDATE FREQUENCY NONE UPDATE MINIMUM 1 INDEX CONFIGURATION(IGNOREEMPTYDOCS 1 , UPDATEAUTOCOMMIT 100)');


Une ligne est ajoutée dans SYSTEXTINDEXES (Nom système : SYSTXTINDX)

la table de transfert est créé dans QSYS2 (son nom est précisé dans STAGINGTABLENAME), les trois triggers sont ajoutés à la table indexée afin d'écrire dans la table de transfert

un répertoire est créé dans l'IFS (répertoire /QOpenSys/QIBM/ProdData/TextSearch/server1/config/collections)
son nom est indiqué par COLLECTIONNAME (par exemple 0_1_3_2010_09_28_17_10_36_131543, pour l'index 3 créé en septembre 2010)

Une vue est créé portant le nom de l'index (PRODUCTEURS_IX) dans la bibliothèque indiquée. C'est le seul objet pouvant être sauvegardé par SAVOBJ.SAVLIB.
  La restauration de la vue, recréé l'index de recherche OmniFind (sans les données) et relance l'indexation.

 

Ensuite, il vous lancer la procédure de mise à jour (l'index est créé vide par SYSTS_CREATE) :

CALL SYSPROCS.SYSTS_UPDATE


l'index est alors créé dans le répertoire de la collection (la création prend au moins 3 à 5 fois le temps de création d'un index "normal")

 


-> Pour détruire l'index


CALL SYSPROCS.SYSTS_DROP

 

-> Pour modifier les caractéristiques de l'index


CALL SYSPROCS.SYSTS_ALTER

 

Recherche

Deux fonctions sont à votre disposition :

Exemple :

SELECT * FROM bdvin1.producteurs 
WHERE contains(pr_avis,'excellent') = 1

 

Que mettre dans une expression de type texte

Exemple :

select pr_avis FROM bdvin1/producteurs WHERE               
contains(pr_avis, 'chateau AND (pomerol OR lafite)') = 1 ;


trouve les lignes contenant chateau ou château ou châteaux puis, soit pomerol, soit lafite.

 

On peut même créer un dictionnaire de synonymes personnel en créant un fichier XML

Exemple :

<?xml version="1.0" encoding="UTF-8"?>
<synonymgroups version="1.0">
<synonymgroup>
<synonym>vin</synonym>
<synonym>pinard</synonym>
<synonym>picrate</synonym>
<synonym>nectar</synonym>
</synonymgroup>
<synonymgroup>
<synonym>syrah</synonym>
<synonym>schiraz</synonym>
</synonymgroup>

</synonymgroups>

puis en passant la commande (sous QSH)

synonymTool.sh importSynonym
-synonymFile <chemin du fichier XML>
-collectionName <nom de la collection>
-replace <[true|false]>
-configPath <chemin absolu du dossier de config.>
Exemple
> cd /QopenSys/QIBM/ProdData/TextSearch/server1/bin > synonymTool.sh importSynonym
-synonymFile /temp/vin_synonyme.xml
-collectionName 0_1_3_2010_09_28_17_10_36_131543 -replace false
-configPath /QopenSys/QIBM/ProdData/TextSearch/server1/config

IQQD0084I The request was successfully executed.
$

 

select count(*) FROM bdvin1/producteurs WHERE
contains(pr_avis, 'pinard')= 1 Donne 1 (pinard est le nom d'un producteur de Cognac) select count(*) FROM bdvin1/producteurs WHERE
contains(pr_avis, 'pinard', 'SYNONYM=ON')= 1 Donne 606

 

Recherche XML

La syntaxe des recherches XML utilise un sous-ensemble du langage W3 XPath

sous la forme CONTAINS(nom_colonne, '@xmlxp: ' 'expression_requête_Xpath' '   ')
le deuxième paramètre de la fonction CONTAINS est une chaîne donc entre quote ('), l'expression XPath étant elle même entre quotes il faut doubler ces dernières

vous devez indiquer un chemin dans l'arborescence XML :

Expression XPath Signifie
/ sélectionne le nœud, dit root element, qui englobe tout le document sauf <?xml version="1.0"?>
// sélectionne tous les noeuds
. sélectionne le nœud en cours
/customerinfo sélectionne le nœud "customerinfo"
//city sélectionne tous les éléments "city" du document où qu'ils soient
/customerinfo/name sélectionne l'unique élément "name" fils de "customerinfo"

puis, éventuellement, un Predicat (un test) devant être vrai, toujours entre crochets [ et ]

Prédicat Signifie
//phone[. = "xxx"] sélectionne tous les éléments "phone" du document (où qu'ils soient), ayant une valeur égale à xxx
//phone[@type = "work"] sélectionne tous les éléments "phone" du document, ayant un attribut "type" dont la valeur est "work"

Pour les valeurs :

Exemples :

INSERT INTO Customer (Cid, Info) VALUES (1000,        
'<customerinfo xmlns="http://posample.org" Cid="1000">
<name>Kathy Smith</name>
<addr country="Canada">
<street>5 Rosewood</street>
<city>Toronto</city>
<prov-state>Ontario</prov-state>
<pcode-zip>M6W 1E6</pcode-zip>
</addr>
<phone type="work">416-555-1358</phone>
</customerinfo>') INSERT INTO Customer (Cid, Info) VALUES (1002,
'<customerinfo xmlns="http://posample.org" Cid="1002">
<name>Jim Noodle</name>
<addr country="Canada">
<street>25 EastCreek</street>
<city>Markham</city>
<prov-state>Ontario</prov-state>
<pcode-zip>N9C 3T6</pcode-zip>
</addr>
<phone type="work">905-555-7258</phone>
</customerinfo>') INSERT INTO Customer (Cid, Info) VALUES (1003,
'<customerinfo xmlns="http://posample.org" Cid="1003">
<name>Robert Shoemaker</name>
<addr country="Canada">
<street>1596 Baseline</street>
<city>Aurora</city>
<prov-state>Ontario</prov-state>
<pcode-zip>N8X 7F8</pcode-zip>
</addr>
<phone type="work">905-555-2937</phone>
</customerinfo>')

 

-- liste des clients possédant un noeud "name" dans la zone XML INFO
SELECT * from posample/customer
where contains(info, '@xmlxp:''//name'' ') = 1 ....1....+.
CID
1.000 1.002 1.003


-- liste des clients possédant un noeud "phone" = à 416-555-1358
SELECT * from posample/customer
where contains(info, '@xmlxp:''//phone[. = "416-555-1358"]'' ')=1

....1....+.
CID
1.000


-- liste des clients possédant un noeud "phone" contenant 905
SELECT * from posample/customer
where contains(info,'@xmlxp:''//phone[. contains("905") ]'' ') = 1 ....1....+.
CID
1.002
1.003

 

-- liste des clients possédant le nœud "phone" de customerinfo = 416-555-1358
SELECT * from posample/customer
where contains(info,'@xmlxp:''/customerinfo[phone = "416-555-1358"]'' ')=1

....1....+.
CID
1.000

La PTF SI40272 ainsi que le dernier niveau de GROUP PTF pour DB2 (level 9) apporte à Omnifind, deux fonctions supplémentaires

 

Vous devez d'abord créer une collection pour stocker ces informations, cela va créer une bibliothèque, contenant

Ensuite vous devez accorder des droits à la procédure cataloguée SEARCH qui vient d'être créé

SET CURRENT SCHEMA OMNI_COL

GRANT EXECUTE ON PROCEDURE SEARCH(VARCHAR) TO QPGMR

 

comment ajouter des objets à l'index, toujours par procédure cataloguée

Il faut toujours commencer par définir la collection dans le chemin de recherche des procédures cataloguées

SET CURRENT PATH OMNI_COL

Ensuite vous devez rafraîchir l'index OmniFInd pour indexer réellement

CALL UPDATE

 

enfin vous pouvez faire des recherches, par CALL SEARCH('mot-recherché')

cela retourne un "result set" structuré comme suit :

Exemple

structure de la zone OBJECTINFOR

Autres procédures

QUERY_OBJECT_SET
   Retourne la liste des objets indexés

GET_OBJECT_STATUS
  retourne le status d'un objet

GET_OBJECTS_NOT_INDEXED
  retourne la liste des objets non indexés

STATUS
  retourne le status du serveur

SYSTS_DRPCOL
  détruit une collection

Pour de plus amples détails, voyez la documentation http://www-03.ibm.com/systems/resources/systems_power_ibmi_omnifind_extensions_user_guide.pdf


Dernière nouveauté (SF99701 , level 18)

-> Possibilité d'indexer des membres sources

Attention, seules les collections créées après cette PTF contiennent la procèdure.

Pour créer la procédure dans les collections existantes passer la commande suivante :

CALL QDBTSLIB/QDBTSUPGRD; -- concernent toutes les collections Omnifind

CALL QDBTSLIB/QDBTSUPGRD ('OMNI_COL'); -- concernent uniqument cette collection

 

cela retourne un "result set" structuré comme pour les spools et les fichiers IFS :

Exemple

Structure de la zone OBJECTINFOR

 

Un même index, peut indexer des spools, des fichiers streams et des membres sources

 

Pour arrêter l'indexation, retrouver le SETID par QUERY_OBJECT_SET

puis,




La PTF SI48982 propose une nouvelle procédure pour OmniFind lors de l'indexation de fichiers de l'IFS : ADD_IFS_STMF_OBJECT_SET_WITH_SUBDIR

permettant lors de l'ajout d'un répertoire à un Index Omnifind, d'ajouter automatiquement les sous répertoires


Après l'installation de la PTF, là aussi, il faut passer CALL QDBTSLIB/QDBTSUPGRD.



Cette option se retrouve dans Navigator for i.



L'option Create collection propose un interface à la procédure SYSTS_CRTCOL


L'option Collection List, liste les index Omnifind créés par SYSTS_CRTCOL
, properties permettant une maintenance des objets indéxés

->

Enfin Search permet une recherche dans l'index


Résultat


Avec la 7.2, Omnifind passe en version 1.3.

- Cette version peut être installée alors que vous avez une version 1.2, une migration sera faite.


- Cette version contient bien sûr, les fonctionnalités d'indexation apportées en V1R2 , via PTF

Autre nouveautés :


 Liens 

Accès à la documentation officielle

V1R2 : http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzash/rzash.pdf

V1R3 : http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzash/rzashpdf.pdf