ページの先頭行へ戻る
Symfoware Server V12.7.0 RDB運用ガイド(Textアダプタ編)
FUJITSU Software

2.8.1 Accela BizSearch 開発キットを使用したサンプルプログラム

全文検索を実施した結果、獲得できる情報を用いて、データベースから文書データ全体と、付随するデータを獲得するサンプルプログラムを示します。サンプルプログラムには、“図2.7 BLOB型の列の文書データを全文検索の対象とする場合(2)”に示す構成を使用します。

参照

データベースと連携しない検索アプリケーションについては、“Accela BizSearch プログラマーズガイド”のサンプルプログラムを参照してください。

サンプルプログラムは、以下の条件を前提とします。

サンプルプログラムは、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アダプタ定義で指定
Textアダプタ定義
<TextAdapterDef>
   <ReplicationDef>
     <REPNAME>書籍データ抽出定義</REPNAME>
   </ReplicationDef>
   <MappingDef>
     <TargetSearchDBname>SearchDB1</TargetSearchDBname>
     <Column  name = 'コード' > code</Column>
     <Column  name = '概要' > contents</Column>
   </MappingDef>
</TextAdapterDef>

サンプルプログラムは以下の手順で処理を実施します。

  1. Accela BizSearchの初期化を行います。

  2. 検索サーバとの接続を確立します。

  3. 検索データベースの回答用文書情報サイズを取得します。

  4. 検索要求を発行し、インデックスから検索結果を取得します。

  5. 取得した結果から必要な回答フィールドの情報を抽出します。

  6. 検索サーバとの接続を切断します。

  7. Accela BizSearchの終了処理を行います。

  8. インデックス対象のデータベースとの接続処理を行います。

  9. 5で取得した情報のうち、一意性制約(PRIMARY KEY)の列値を検索条件にしてSQLを発行し、文書データを取得します。

  10. インデックス対象のデータベースとの切断処理を行います。

以下にサンプルプログラムを示します。

/*
*  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");
}