概述
Searcher 模块作为搜索引擎的上层封装,主要负责接收用户查询请求,调用底层索引服务,并将最终结果序列化为标准格式返回。其核心流程包括索引初始化、查询词处理、结果合并排序及数据序列化。
索引初始化
模块采用单例模式管理索引实例,确保全局唯一性。初始化时创建或获取 Index 对象,并构建正倒排索引结构。
private: ns_index::Index* index;
public: Searcher(){}; ~Searcher(){};
public: void InitSearcher(const std::string& input) {
// 获取单例索引对象
index = ns_index::Index::GetInstance();
// 根据输入路径建立索引
index->BuildIndex(input);
LOG1(NORMAL,"建立索引成功...");
}
搜索流程
搜索函数主要包含分词、触发、合并排序和构建 JSON 结果四个步骤。
1. 分词
利用 Jieba 工具对用户输入的查询字符串进行切分,生成关键词列表。
std::vector<std::string> words;
ns_util::JiebaUtil::CutString(query, &words);
2. 触发与去重
遍历分词后的关键词,从倒排索引中获取对应的文档列表。由于同一文档可能匹配多个关键词,直接使用向量会导致重复,因此引入哈希表 tokens_map 进行去重与权重累加。同时通过 boost::to_lower 统一转为小写,忽略大小写差异。
std::unordered_map<uint64_t, InvertedElemPrint> tokens_map;
for(std::string w : words) {
boost::to_lower(w);
ns_index::InvertedList* inverted_list = index->GetInvertedList(w);
if(inverted_list == nullptr) continue;
for(const auto &elem : *inverted_list) {
auto &item = tokens_map[elem.doc_id];
item.doc_id = elem.doc_id;
item.weight += elem.weight;
item.words.push_back(elem.word);
}
}


