精準搜尋

JZSearch全文精準搜尋中間件核心經過精心設計,具有高擴展性和高通用性。還可與現有資料庫系統融合,可支持文本、數字、日期、字元串等各種數據類型的高效索引,支持豐富的查詢語言和查詢類型,支持少數民族語言的搜尋。

基本介紹

  • 中文名:精準搜尋
  • 特色:支持指定欄位的搜尋
  • 支持:少數民族語言的搜尋
  • 按照:任意指定欄位的排序
  • 服務:多執行緒搜尋
全文精準搜尋,建立索引接口,全文檢索接口,檢索語法說明,建立索引的示例程式,搜尋系統的示例程式,

全文精準搜尋

其主要特色在於:
* 可以按照任意指定欄位的排序,支持指定欄位的搜尋,也可以搜尋多個欄位,以及複雜表達式的綜合搜尋
* 支持精確匹配以及模糊匹配,默認為精確匹配,忽略字母大小寫進行模糊匹配;
* 實現的是多執行緒搜尋服務;
* 每秒可索引3000條記錄(主要瓶頸為資料庫或檔案記錄的讀取效率);搜尋速度在毫秒級別。
* 兼容當前所有廠商的資料庫系統,其中SQL Server, Oracle, MySQL,DB2等。

建立索引接口

(1)索引初始化操作
/*********************************************************************
*
* Func Name : LJIndexer_Init
*
* Description: 索引系統初始化,必須初始化後,才能使用CLJIndexer
*
* Parameters : sDictFilename:詞典檔案名稱;為空時,採用n-gram索引方法
* sFieldInfoFile:域欄位信息,用於支持多域索引,為空則只支持一個欄位
* 如果API定義了CODE_LIMIT,需要從開發商處獲得授權碼,作為第三個參數
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
#ifndef CODE_LIMIT
LJSEARCHAPI_API bool LJIndexer_Init(const char *sDictFilename=0,const char *sFieldInfoFile=0);
#else
LJSEARCHAPI_API bool LJIndexer_Init(const char *sDictFilename=0,const char *sFieldInfoFile=0,const char *sLicenseCodes=0);
#endif
(2)多欄位定義操作
/*********************************************************************
* 系統定義的欄位數據類型
*
*********************************************************************/
#define FIELD_TYPE_TEXT 1 //文本類型
#define FIELD_TYPE_INT 2 //整型
#define FIELD_TYPE_LONG 3 //長整型
#define FIELD_TYPE_DATETIME 4 //日期類型
/*********************************************************************
*
* Func Name : LJIndexer_FieldAdd
*
* Description: 添加欄位信息
*
* Parameters : sFieldName:域名稱,在索引建立與搜尋過程中,域的唯一標示符
* sDBFieldName:對應於資料庫的欄位名稱;在資料庫搜尋的時候,用於獲取資料庫的數據
* nFieldType:數據類型,對應的範圍如下:
* //FIELD_TYPE_TEXT
* //FIELD_TYPE_INT
* //FIELD_TYPE_LONG
* //FIELD_TYPE_DATETIME
* bIndexed:是否需要索引
* bRetrieved:搜尋結果中是否要輸出該欄位內容
* bGeneral:是否納入通配搜尋的範疇
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJIndexer_FieldAdd(const char *sFieldName,const char *sDBFieldName,int nFieldType,bool bIndexed,bool bRetrieved,bool bGeneral=false);
/*********************************************************************
*
* Func Name : LJIndexer_FieldSave
*
* Description: 保存欄位定義的內容,一般都在定義完LJIndexer_FieldAdd之後,執行
*
* Parameters : sFieldInfoDataFile:保存的域信息數據檔案
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJIndexer_FieldSave(const char *sFieldInfoDataFile);
/*********************************************************************
*
* Func Name : LJIndexer_FieldLoad
*
* Description: 讀取已經保存好的域信息數據檔案
*
* Parameters : sFieldInfoDataFile:保存的域信息數據檔案
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJIndexer_FieldLoad(const char *sFieldInfoDataFile);
(3)索引系統退出
/*********************************************************************
*
* Func Name : LJIndexer_Exit
*
* Description: 索引系統退出,索引相關的記憶體全部釋放
*
* Parameters :
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJIndexer_Exit();
(4)索引合併操作
/*********************************************************************
*
* Func Name : LJIndexer_Merge
*
* Description: 索引合併,要求sIndexFile1的doc_id編號均小於sIndexFile2的doc_id
*
* Parameters : sIndexFile1:索引檔案1
* sIndexFile2:索引檔案2
* sIndexMerged:索引合併後的檔案名稱
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJIndexer_Merge(const char *sIndexFile1,const char *sIndexFile2,const char *sIndexMerged);
(5)索引類操作
/*********************************************************************
*
* Func Name : CLJIndexer
*
* Description: 建立索引的類
*
* Parameters :
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
//
class LJSEARCHAPI_API CLJIndexer {
public:
CLJIndexer(int nMaxMemSize=512000000);
//記憶體大小控制
~CLJIndexer(void);
// TODO: add your methods here.
int MemIndexing(const char *pText,int doc_id,const char *sFieldName=0,int nMemSize=0);
//索引一段記憶體;
//pText:待索引的記憶體塊指針
//doc_id由應用程式維護,
//sFieldName:欄位名稱,為空則表示無欄位信息,則該索引不支持多欄位索引與檢索
//nMemSize:指的是pText記憶體塊的大小,默認為0,需要系統通過strlen自行計算記憶體大小
int FileIndexing(const char *sTextFilename,int doc_id,const char *sFieldName=0);
//索引一個文本檔案
//sTextFilename:文本檔案名稱
//doc_id由應用程式維護
//sFieldName:欄位名稱,為空則表示無欄位信息
int IdIndexing(int term_id,int doc_id,const char *sFieldName=0);
//詞ID索引
//term_id:詞ID
//doc_id由應用程式維護
//sFieldName:欄位名稱,為空則表示無欄位信息
bool Save(const char *sIndexFile);
//索引保存的名稱
//一般都選擇在索引建立全部完成後,調用。
private://以下部分為系統使用,套用開發者不要改寫,只能讀取數據
int m_nHandle;//索引器的Handle,無需調用申請
};

全文檢索接口

(1)搜尋的排序選項
/*********************************************************************
* 搜尋的排序選項
*
*********************************************************************/
#define SORT_TYPE_DOCID 1//按照Doc ID排序,默認方式
#define SORT_TYPE_RELEVANCE 2//按照相關度排序
(2)搜尋的初始化設定
/*********************************************************************
*
* Func Name : LJSearch_Init
*
* Description: 搜尋系統初始化,必須初始化後,才能使用CLJSearch
*
* Parameters :sIndexFile:已經建立的索引檔案
* sDictFilename:詞典檔案名稱;為空時,採用n-gram索引方法
* sFieldInfoFile:域欄位信息,用於支持多域索引,為空則只支持一個欄位
* 如果API定義了CODE_LIMIT,需要從開發商處獲得授權碼,作為第三個參數
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
#ifndef CODE_LIMIT
LJSEARCHAPI_API bool LJSearch_Init(const char *sIndexFile,const char *sDictFilename=0,const char *sFieldInfoFile=0);
#else
LJSEARCHAPI_API bool LJSearch_Init(const char *sIndexFile,const char *sDictFilename=0,const char *sFieldInfoFile=0,const char *sLicenseCodes=0);
#endif
(3)搜尋系統的退出
/*********************************************************************
*
* Func Name : LJSearch_Exit
*
* Description: 搜尋系統退出,釋放所有相關的記憶體
*
* Parameters :
* Returns : success or fail
* Author : 靈玖軟體
* History :
*********************************************************************/
LJSEARCHAPI_API bool LJSearch_Exit();
//系統退出
(4)搜尋結果的記憶體存儲格式
/*********************************************************************
*
* Data Structure Name : tRESULT_RECORD
*
* Description: 搜尋結果結構,用於檢索計算使用
*
* Parameters :
* Returns :
* Author : 靈玖軟體
* History :
*********************************************************************/
typedef struct tRESULT_RECORD {//搜尋結果結構,用於檢索計算使用
int doc_id;
int offset;//在域欄位內的偏移量
double score;//排序用的打分
}RESULT_RECORD;
typedef RESULT_RECORD * RESULT_RECORD_VECTOR;
(5)搜尋類
/*********************************************************************
*
* Class Name : CLJSearcher
*
* Description: 用於搜尋的類
*
* Parameters :
* Returns :
* Author : 靈玖軟體
* History :
*********************************************************************/
//
class LJSEARCHAPI_API CLJSearcher{
public:
CLJSearcher(int sort_type=SORT_TYPE_DOCID);
~CLJSearcher(void);
// TODO: add your methods here.
void Search(const char *query_line,int nStart,int nPageCount,const char *sResultName);
//query_line: 查詢表達式
//nStart:記錄起始地址
//nPageCount:當前頁返回結果數目
//nPageCount=-1:當前頁需要返回所有的結果數目
//sResultName:結果存儲的XML地址
const RESULT_RECORD_VECTOR CLJSearcher::Search(const char *query_line,int *p_nResultCountRet);
//query_line: 查詢表達式
//p_nResultCountRet:搜尋結果總數
private://以下部分為系統使用,套用開發者不要改寫,只能讀取數據
int m_nHandle;
int m_nSortType;//排序方法編號
};

檢索語法說明

/*********************************************************************
*
* 查詢表達式語法說明
*
*********************************************************************/
/*********************************************************************
{[FIELD] fieldname [AND/OR/NOT/NEAR/PREC] value1 value2 ... value_n}+
說明:
1.查詢是由 [FIELD] fieldname [AND/OR/NOT/NEAR/PREC] value1 value2 ... value_n 形式的表達式無限疊加組成的;可以針對多個欄位進行查詢,也可以針對同一個欄位編寫多條查詢語句;
2.其中每個字元串之間採用空格或者TAB鍵隔開;
3.其中[FIELD]指定欄位名稱;
4.[AND/OR/NOT/NEAR/PREC]為候選的操作符;操作符的意義解釋如下:
1) AND: 與操作,即返回的結果必須同時包括後面指定的值value1 value2 ... value_n;
2) OR: 或操作,即返回的結果必須包括後面指定值範圍value1 value2 ... value_n中的任意一個;
3)NOT: 非操作,即返回的結果不能包括後面指定值範圍value1 value2 ... value_n中的任意一個;
4)NEAR: 鄰接操作:即返回的結果中,後續的搜尋串value1 value2 ... value_n必須出現在鄰接的位置上(系統目前自定義為10個詞間隔)
5)PREC: 精準操作:即返回的結果中,如果包含數據的話,必須嚴格匹配:例如檢索號碼“GB 997”,不能命中“GB 1997-2009”,或者"GB 9970",只能是“GB 997”或者"GB 997-2008"。
5.fieldname為索引欄位名稱,必須和實現建立索引對應的欄位名一致;
也可以給出通配符 *,表示在指定的通配符欄位範圍內任意搜尋;
6.檢索語法示例:
//Sample1: [FIELD] title [AND] 解放軍
//Sample2: [FIELD] title [AND] 甲流
//Sample3: [FIELD] title [AND] 解放軍 甲流
//Sample4: [FIELD] title [OR] 解放軍 甲流
//Sample5: [FIELD] title [AND] 解放軍 [FIELD] title [NOT] 甲流
//Sample6: "[FIELD] content [AND] 解放軍 張雁靈 [FIELD] title [AND] 解放軍
//Sample7: "[FIELD] content [AND] 解放軍 張雁靈 [FIELD] title [AND] 解放軍
//Sample8: [FIELD] title [AND] 解放軍某部發生數百人感染甲流疫情
//Sample9: [FIELD] title [AND] 解放軍某部發生數百人感染甲流疫情
//Sample10: [FIELD] content [AND] 甲型H1N1流感
//Sample11: [FIELD] content [NEAR] 張雁靈 解放軍
//Sample12: [FIELD] content [AND] 解放軍 [FIELD] content [NOT] 張雁靈
*********************************************************************/

建立索引的示例程式

//////////////////////////////////////////////////////////////////////////
//
// 以下部分為索引建立的API調用示例
//
//////////////////////////////////////////////////////////////////////////
//索引初始化
LJIndexer_Init("E:/LJSearch20/Data/dictionary.pdat",NULL,"LingjoinICTCLAS2010*~!@#$%&&%$#@!~*");
//設定欄位信息
LJIndexer_FieldAdd("title",NULL,FIELD_TYPE_TEXT,true,true,true);
//對標題建索引,需要搜尋
LJIndexer_FieldAdd("content",NULL,FIELD_TYPE_TEXT,true,true,true);
//對內容建索引,需要搜尋
LJIndexer_FieldSave("FieldInfo.dat");
//保存欄位信息
CLJIndexer *pIndexer=new CLJIndexer();
//對文檔列表進行索引
for (int doc_id=0;doc_id<vecFileList.size();doc_id++)
{//索引一個檔案,注意:vecFileList存儲的是檔案名稱向量
pIndexer->MemIndexing(vecFileList[doc_id].c_str(),doc_id,"title");
//對檔案標題進行索引
printf("Indexing %s title completed!\n",vecFileList[doc_id].c_str());
pIndexer->FileIndexing(vecFileList[doc_id].c_str(),doc_id,"content");
//對檔案內容進行索引
printf("Indexing %s content completed!\n",vecFileList[doc_id].c_str());
}
pIndexer->Save("Test0430test");//保存索引結果
delete pIndexer;//索引完成,釋放空間
LJIndexer_Exit();//退出索引系統

搜尋系統的示例程式

LJSearch_Init("Test0430test","E:/LJSearch20/Data/dictionary.pdat","FieldInfo.dat","LingjoinICTCLAS2010*~!@#$%&&%$#@!~*");
CLJSearcher *pSearcher=new CLJSearcher(SORT_TYPE_RELEVANCE);//按照相關度排序
//申請搜尋類
int nRecordCount=0;
RESULT_RECORD_VECTOR pResult =0;
int nLen;
char *pQueryString,*sLine;
sLine=new char[100];
strcpy(sLine,"[FIELD] content [AND] 解放軍 張雁靈");//甲型H1N1流感
//Sample1: [FIELD] title [AND] 解放軍
//Sample2: [FIELD] title [AND] 甲流
//Sample3: [FIELD] title [AND] 解放軍 甲流
//Sample4: [FIELD] title [OR] 解放軍 甲流
//Sample5: [FIELD] title [AND] 解放軍 [FIELD] title [NOT] 甲流
//Sample6: "[FIELD] content [AND] 解放軍 張雁靈 [FIELD] title [AND] 解放軍"
//Sample7: "[FIELD] content [AND] 解放軍 張雁靈 [FIELD] title [AND] 解放軍"
//Sample8: [FIELD] title [AND] 解放軍某部發生數百人感染甲流疫情
//Sample9: [FIELD] title [AND] 解放軍某部發生數百人感染甲流疫情
//Sample10: [FIELD] content [AND] 甲型H1N1流感
//Sample11: [FIELD] content [NEAR] 張雁靈 解放軍
//Sample12: [FIELD] content [AND] 解放軍 [FIELD] content [NOT] 張雁靈
int nSize=0;
pQueryString=sLine;
pResult=pSearcher->Search(pQueryString,&nRecordCount);
//搜尋pQuerySearch,結果總數存在nRecordCount內,搜尋結果數組指針存儲在pResult
printf("Query=%s, Search Result Count=%d, list as follows:\n",pQueryString,nRecordCount);
//逐個輸出搜尋結果
for (int i=0;i<nRecordCount;i++)
{
printf("No.%d:doc_id=%d===%s[%d] score=%f\n",
i,
pResult[i].doc_id,
vecFileList[pResult[i].doc_id].c_str(),
pResult[i].offset,
pResult[i].score
);
}
delete pSearcher;//釋放搜尋類
delete sLine;
LJSearch_Exit();//退出搜尋系統

相關詞條

熱門詞條

聯絡我們