xapian-xunsearch的後端

Xapian 是一款開源的C++信息檢索系統,內部系統試用了xunsearch,所以稍微瞭解了一下「蝦片」的機制 html

先看一下執行過程: 數據庫


檢索相關:
Xapian::Database 用於讀取索引。
Xapian::Enquire 提供檢索服務,與Xapian::Database配合使用
Xapian::QueryParser 查詢語句解析器
Xapian::Query 查詢語句
Xapian::MSet 檢索返回的匹配結果記錄集

建索引相關:
Xapian::WritableDatabase 用於創建索引。
Xapian::TermGenerator 很是簡單的切詞、建索引器,不是必須使用的,可用其餘替代,可是提供了一些幫助函數,很是好用。

共用:
Xapian::Document 文檔的抽象。
Xapian::SimpleStopper 停用詞
Xapian::Error 異常類,.get_description()獲取詳細信息。

後端相關:
Xapian::Database::Internal     每一個後端都要實現

Database,也能夠稱爲Index
Database類型
- auto
     - 
- brass
     - 當前開發中的後端,並將做爲1.4.x版本起的默認後端
- chert
     - 1.2.x的默認後端,支持增量修改、單寫者+多讀者的併發。
     - 高效且可擴展
- flint
     - 1.0.x的默認後端,類chert
- inmemory
     - 全內存的database,可用於創建臨時小database
- quartz
     - 1.0的默認後端,1.1.0後移除 

文檔
- 粒度
     - RMDB:表中的一條記錄
     - html:一個html文件/一個標籤
- 表示方式
     - 32位 Document ID
     - 3個組分
          - 數據data
               - 只存儲,不分析其內容,一般用於結果的返回
               - 是文檔的部分/所有數據
          - 詞集terms
               - 基本的查詢單元
          - 值域集values

分詞器
- xapian沒有Field的概念,經過在每一個詞前加前綴來標識
須要注意的是,在Xapian中,若是你在索引的時候使用了TermGenerate來進行分詞,那在查詢的時候必定要使用QueryParser來對查詢條件進行解析

索引
一些限制:
- Term Length:一個詞限制在256個字節內,
- Document Data:一個data區不能大於100MB,默認是8KB
- Document value:和一個data區的限制是同樣的,但通常建議value不要太大
- Document ID: 當前範圍是32bit,大概在43億左右,文檔刪除的ID號不會被從新利用,除非你對數據庫進行compact
- B-tree block number: 目前支持最大爲32bit個塊
- OS file size:全部操做系統對於單個文檔的限制對於Xapian都適用,如ext4對於單個文件的大小爲16TB,
- Document length:文檔長度的存儲限制爲unsigned 64bit

索引格式
- Xapian有多種數據庫格式 

分面搜索(faceted search)
- 將搜索結果進行聚類處理

並行讀寫操做
- 寫
     -  數據庫只支持單個數據庫寫對象存在
     -  也就是說在建立一個DataBaseWritable對象的時候,會對數據庫進行加鎖,若是另外一個寫數據庫對象再去寫這個數據庫時,會出現DatabaseLockError錯誤。
- 讀
     -  可是多個讀對象是同時存在於同一個數據庫。
- 更新
     -  讀/寫操做隔離
         -  當打開一個數據庫準備進行讀操做時,會建立一個找開數據庫的鏡像,這樣有寫操做時,讀對象是不可見的,除非讀對象運行reopen()操做。
     - 限制
          -  如今的Xapian多版本同步仍是有一些限制的,特別是當數據庫有兩個版本同時存在時,也就是說有多個讀,一個寫數據庫操做時,當寫數據庫只修改了數據庫,運行了一次commit時,是沒問題的,可是當寫數據庫又運行了第二次commit時,讀數據庫操做會收到了一個Xapian::DatabaseModifiedError,在這種狀況下,讀數據庫操做要更新其數據庫的鏡像版本,使用reopen()操做,這個要在編程上注意一下。

數據同步
同時支持數據庫的複製,並且只複製那些變動過的索引數據,這樣可使用數據冗餘,達到負載均衡的目的 


常見問題
DatabaseLockError錯誤
- 數據庫只支持單個數據庫寫對象存在,也就是說在建立一個DataBaseWritable對象的時候,會對數據庫進行加鎖,若是另外一個寫數據庫對象再去寫這個數據庫時,會出現DatabaseLockError錯誤
- 可是多個讀對象是同時存在於同一個數據庫。

DatabaseModifiedError錯誤
- 當打開一個數據庫準備進行讀操做時,會建立一個找開數據庫的鏡像,這樣有寫操做時,讀對象是不可見的,除非讀對象運行reopen()操做。這樣讀/寫操做就隔離了。
- 如今的Xapian多版本同步仍是有一些限制的,特別是當數據庫有兩個版本同時存在時,也就是說有多個讀,一個寫數據庫操做時,當寫數據庫只修改了數據庫,運行了一次commit時,是沒問題的,
- 可是當寫數據庫又運行了第二次commit時,讀數據庫操做會收到了一個Xapian::DatabaseModifiedError,在這種狀況下,讀數據庫操做要更新其數據庫的鏡像版本,使用reopen()操做。

- 多線程支持
- Xapian沒有顯示的支持多線程,爲了不沒必要要的線程死鎖,Xapian沒有使用任何全局變量,因此你能夠你的多線程應用中放心的使用Xapain對象。
- 可是一些Xapian對象內部是有關聯的,如Xapian::Database::get_document(),返回的對象Xapian::Document對象內部保存了一個指向DataBase的一個引用,因此它不適合在多線程中使用,因此在多線程中使用Xapian的時候仍是要注意一些東西的。
相關文章
相關標籤/搜索