全文検索を実施した結果、獲得できる情報を用いて、データベースから文書データ全体と、付随するデータを獲得するサンプルプログラムを示します。サンプルプログラムには、“図2.7 BLOB型の列の文書データを全文検索の対象とする場合(2)”に示す構成を使用します。
参照
データベースと連携しない検索アプリケーションについては、“Accela BizSearch プログラマーズガイド”のサンプルプログラムを参照してください。
サンプルプログラムは、以下の条件を前提とします。
文書データは、「概要」列に格納します。「概要」列はVARCHAR型であるため、格納される文書データは、すべてテキスト文書です。
Accela BizSearchの検索データベース名は、「SearchDB1」です。
検索モードは、ブーリアン検索モードです。
「コード」列に、一意性制約(PRIMARY KEY)が付いています。また、「コード」列はcodeフィールドに対応しています。
サンプルプログラムは、contentsフィールドに対して、検索条件を指定し、検索結果としてcodeフィールドのデータを獲得します。獲得したcodeフィールドのデータを指定し、SQLを発行することで、検索結果に該当する文書データ(「概要」列のデータ)と文書データに付随する情報(「書名」列のデータ)をデータベースから取り出します。
図2.16 サンプルプログラムで前提とする構成
REPNAME = 書籍データ抽出定義 REPTYPE = TEXTADP DBMSKIND = SYMFO DATABASE = 書籍データベース SCHEMA = 書籍スキーマ TABLE = 書籍表 SELECT = コード,概要 LOGPATH=/home/work/logdata_db01 LOGSIZE = 1G,LARGE LOGTYPE = LITTLE
database - string(40) - schema - string(40) - table - string(40) - ROW_ID JAPANESE string(48) id code - interger(4) - ← 「コード」列に対応するようにTextアダプタ定義で指定 contents JAPANESE string(256) - ←「概要」列に対応するようTextアダプタ定義で指定
<TextAdapterDef> <ReplicationDef> <REPNAME>書籍データ抽出定義</REPNAME> </ReplicationDef> <MappingDef> <TargetSearchDBname>SearchDB1</TargetSearchDBname> <Column name = 'コード' > code</Column> <Column name = '概要' > contents</Column> </MappingDef> </TextAdapterDef>
サンプルプログラムは以下の手順で処理を実施します。
Accela BizSearchの初期化を行います。
検索サーバとの接続を確立します。
検索データベースの回答用文書情報サイズを取得します。
検索要求を発行し、インデックスから検索結果を取得します。
取得した結果から必要な回答フィールドの情報を抽出します。
検索サーバとの接続を切断します。
Accela BizSearchの終了処理を行います。
インデックス対象のデータベースとの接続処理を行います。
5で取得した情報のうち、一意性制約(PRIMARY KEY)の列値を検索条件にしてSQLを発行し、文書データを取得します。
インデックス対象のデータベースとの切断処理を行います。
以下にサンプルプログラムを示します。
/* * Textアダプタ サンプルプログラム */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <is_sdka.h> static void usage(); /* メイン */ int main(int argc, char *argv[]) { isc_status_t iscStatus; iss_status_t issStatus; iss_handle_t handle; int32_t dbsize; int rtn=0; int resultsize; char *result = NULL; int32_t hits; int32_t resnum; int *codebuf = NULL; int i; char *query=NULL; int32_t query_num=0; EXEC SQL BEGIN DECLARE SECTION; VARCHAR OUTLINE[1024]; long CODE; char SQLSTATE[6]; char SQLMSG[256]; EXEC SQL END DECLARE SECTION; if ( argc != 3 ) { usage(); rtn=1; goto ERR; } query = argv[1]; query_num = atoi(argv[2]); if( query_num == 0 ){ fprintf(stderr, "ERROR: Invalid number\n"); rtn=1; goto ERR; } /* Accela BizSearch初期化 */ iscStatus = ISC_Initialize(); if (iscStatus != ISC_STATUS_OK) { fprintf(stderr, "ERROR: ISC_Initialize():%d\n", iscStatus); rtn=1; goto ERR; } /* 検索サーバとの接続 */ issStatus = ISS_ConnectServer(&handle, "localhost", 0); if (issStatus != ISS_STATUS_OK) { fprintf(stderr, "ERROR: ISS_ConnectServer():%d\n", issStatus); rtn=1; goto TERMINATE; } /* 回答用文書情報サイズの獲得 */ issStatus = ISS_GetTotalFieldSize(handle, "SearchDB1", &dbsize); if (issStatus != ISS_STATUS_OK) { fprintf(stderr, "ERROR: ISS_GetTotalFieldSize():%d\n", issStatus); rtn=1; goto DISCONNECT; } /* 検索結果格納領域の獲得 */ if (!(result = malloc(dbsize * query_num))) { fprintf(stderr, "ERROR: Can't allocate result buffer.\n"); rtn=1; goto DISCONNECT; } resultsize = dbsize * query_num; /* ブーリアン検索 */ issStatus = ISS_Search(handle, "SearchDB1", ISS_MODE_BOOLEAN, "contents", ISS_OPERATOR_NONE, query, 0, NULL, 1, query_num, &resnum, &hits, result, resultsize, NULL); if (issStatus != ISS_STATUS_OK) { fprintf(stderr, "ERROR: ISS_Search():%d\n", issStatus); rtn=1; goto SEARCH_FREE; } if( resnum == 0 ){ fprintf(stdout, "It doesn't correspond to the reference condition.\n"); rtn=0; goto SEARCH_FREE; } /* 回答フィールド値格納域の取得と初期化 */ if (!(codebuf = malloc(sizeof(int) * resnum))) { fprintf(stderr, "ERROR: Can't allocate field buffer.\n"); rtn=1; goto SEARCH_FREE; } memset(codebuf,0x0,sizeof(int) * resnum); for (i = 0; i < resnum; i++) { /* 回答フィールド値の取出し */ issStatus = ISS_GetDocFieldValue(handle, "SearchDB1", i + 1, resultsize, result, "code", 4, &codebuf[i]); if (issStatus != ISS_STATUS_OK) { fprintf(stderr, "ERROR: ISS_GetDocFieldValue():%d\n", issStatus); rtn=1; goto ANSWER_FREE; } } memset(SQLSTATE,0x0,6); memset(SQLMSG,0x0,256); /* CONNECT処理 */ EXEC SQL WHENEVER SQLERROR GOTO :SQLERR; EXEC SQL CONNECT TO '書籍データベース'; /* コードに対応する概要列の取出しと表示 */ for (i = 0; i < resnum; i++) { memset( &OUTLINE, 0x0, sizeof(OUTLINE) ); CODE = codebuf[i]; EXEC SQL SELECT 概要 INTO :OUTLINE FROM 書籍スキーマ.書籍表 WHERE コード= :CODE; printf("コード = %d\n",CODE); printf("概要 = %s\n\n",OUTLINE.sqlvar); } /* COMMIT */ EXEC SQL COMMIT WORK; /* DISCONNECT */ EXEC SQL DISCONNECT '書籍データベース'; SQLERR: if( strcmp(SQLSTATE,"00000")!= 0 ){ rtn=1; printf("SQLSTATE = %s SQLMSG = %s\n",SQLSTATE,SQLMSG); } ANSWER_FREE: if( codebuf != NULL ) free(codebuf); SEARCH_FREE: if( result != NULL ) free(result); DISCONNECT: ISS_DisconnectServer(handle); TERMINATE: ISC_Terminate(); ERR: return(rtn); } /* usage */ static void usage(void) { fprintf(stderr, "usage: BooleanSearch query number\n"); }