wwsearch企業(yè)微信檢索引擎
wwsearch簡(jiǎn)介
wwsearch是企業(yè)微信后臺(tái)自研的全文檢索引擎。它為海量用戶下的全文快速檢索而設(shè)計(jì),底層支持可插拔的lsm tree存儲(chǔ)引擎。目前覆蓋企業(yè)微信所有在線檢索場(chǎng)景:企業(yè)員工通訊錄、審批、日?qǐng)?bào)、周報(bào)、匯報(bào)、企業(yè)素材檢索,也包括企業(yè)郵箱的全文郵件檢索。 最大業(yè)務(wù)場(chǎng)景有300+億條記錄,索引詞項(xiàng)萬億+,存儲(chǔ)容量幾十TB,支撐實(shí)時(shí)在線用戶檢索。
功能介紹
- 實(shí)時(shí)數(shù)據(jù)修改:數(shù)據(jù)寫入即實(shí)時(shí)可查。對(duì)外提供插入、更新、刪除、覆蓋寫等接口,可適應(yīng)更新頻繁場(chǎng)景,也適應(yīng)于少改或不改場(chǎng)景。
- 支持靈活Query:支持詞的等值、前綴、模糊匹配。多個(gè)Query通過And 、Or進(jìn)行組合,滿足不同場(chǎng)景的檢索需求。Query還可以按指定field進(jìn)行檢索。
- 后置過濾:支持對(duì)檢索索引后的結(jié)果進(jìn)行二次過濾,支持等值、數(shù)值范圍、數(shù)組元素查找、字符串模糊等過濾特性。適用于如無法建立高區(qū)分度索引的字段過濾、帶有業(yè)務(wù)特定場(chǎng)景的過濾。
- 靈活排序:支持按多個(gè)field的屬性值組合排序,類似order by語義。
- 檢索功能可擴(kuò)展:場(chǎng)景需要時(shí),可以擴(kuò)展各類聚合函數(shù)(sum/avg…),也可以支持場(chǎng)景文本打分。
實(shí)現(xiàn)剖析
接口說明
具體使用例子參考example/example.cpp。 這里簡(jiǎn)單對(duì)接口字段進(jìn)行說明。
Index
主要涉及6個(gè)接口,分別是:
- AddDocuments:僅當(dāng)文檔id不存在時(shí)添加;
- UpdateDocuments:僅當(dāng)文檔id存在時(shí)更新;更新時(shí)會(huì)保留舊文檔存在的未更新field內(nèi)容;
- AddOrUpdateDocuments:若文檔id不存在則添加,若存在則更新;
- ReplaceDocuments:僅當(dāng)文檔id存在時(shí)替換;
- DeleteDocuments:僅當(dāng)文檔id存在時(shí)刪除;
- AddDocumentsWithoutRead:文檔id不存在則添加,存在則覆蓋;
下面以用戶常用的AddOrUpdateDocuments為例說明用法。
// wwsearch/index_writer.h
bool AddOrUpdateDocuments(const TableID &table,
std::vector<DocumentUpdater *> &documents,
std::string *store_buffer = nullptr,
SearchTracer *tracer = nullptr);
// wwsearch/document.h
class DocumentUpdater {
...
Document new_document_;
...
};
class Document {
...
std::vector<IndexField *> fields_;
DocumentID document_id_;
...
};
// wwsearch/index_field.h
class IndexField {
...
FieldID field_id_;
IndexFieldFlag field_flag_;
kIndexFieldType field_type_;
uint64_t numeric_value_;
std::string string_value_;
...
}
用戶使用涉及主要字段說明:
- TableID : bussiness_type(uint8_t) + partition_set(uint64_t)組成,分表;
- DocumentID : uint64_t,文檔id,文檔的唯一標(biāo)識(shí);
- IndexField : 文檔列的信息,包括列屬性和值。
- field_id_,field的ID
- field_flag_,索引標(biāo)記
- kTokenizeFieldFlag,是否分詞
- kStoreFieldFlag,是否存儲(chǔ)原始數(shù)據(jù)
- kDocValueFieldFlag,是否存儲(chǔ)列值屬性
- kSuffixBuildFlag,是否后綴展開
- kInvertIndexFieldFlag,是否建立倒排索引
- field_type_,值類型
- kUint32IndexField
- kUint64IndexField
- kStringIndexField
- numeric_value_/ string_value_,字段原始值
Query
主要涉及接口:
// wwsearch/searcher.h
SearchStatus DoQuery(const TableID &table, Query &query, size_t top,
std::vector<Filter *> *filter,
std::vector<SortCondition *> *sorter,
std::list<DocumentID> &docs,
uint32_t min_match_filter_num = 0)
用戶使用涉及主要字段說明:
- TableID : bussiness_type(uint8_t) + partition_set(uint64_t)組成,分表;
- Query :構(gòu)建查詢的字段信息,可支持AndQuery和OrQuery的嵌套格式,支持PrefixQuery前綴查詢;參考
- Filter :過濾器,支持?jǐn)?shù)字/字符串/數(shù)組/多字符串條件過濾;
- SortCondition :對(duì)查詢得到的文檔輸出做排序,支持指定field做排序,目前只支持指定數(shù)字的field排序;
- min_match_filter_num設(shè)置最小匹配的filter數(shù),只要匹配的filter大于此數(shù)的文檔才能輸出。
構(gòu)建方法
依賴模塊說明
依賴模塊為:
# wwsearch/deps/
protobuf-2.4.1
snappy-1.0.4
rocksdb-v5.16.6
tokenizer-mmseg
倉(cāng)庫(kù)中已提前編譯生成依賴庫(kù),您也可以根據(jù)編譯環(huán)境重新編譯依賴的第三方模塊。
構(gòu)建方法:
需要使用支持c++ 11的編譯環(huán)境構(gòu)建
mkdir build
cd build
cmake ..
make -j32
cp ../deps/tokenizer/etc/wwsearch_* .
編譯完成將可以看到:
- wwsearch_ut : 單元測(cè)試;
- wwsearch_example : 簡(jiǎn)單示例,包括index和query。
接下來可以愉快使用啦,enjoy it!
貢獻(xiàn)代碼
提交pull request貢獻(xiàn)代碼前,請(qǐng)參考 Contributing.md 。 wwsearch基于c++11開發(fā),遵循Google C++ Style Guide代碼風(fēng)格,提交代碼前需要使用附帶的.clang-format格式化代碼;
反饋問題
使用中遇到問題,可以有以下途徑反饋:
- 直接在[issues]提問;
開源協(xié)議
wwsearch 開源協(xié)議為 Apache License Version 2.0 ,詳細(xì)的 License 請(qǐng)參考 LICENSE.TXT
