C++ Boost 搜索引擎:正倒排索引核心实现与详解
在搜索引擎项目中,正排索引与倒排索引是协同工作的核心组件。正排索引将文档内容映射到文档 ID,而倒排索引则根据关键词反向映射到文档列表。构建流程通常先创建正排索引,再基于其生成倒排索引。当用户查询时,系统利用倒排索引快速定位相关文档,并结合正排索引信息展示结果。
注意:索引是在搜索前预先构建的,并非临时创建。
1. 数据结构设计
1.1 正排索引结构
正排索引主要维护文档的元数据,包括标题、内容和 URL。
// 正排索引所需的数据结构
typedef struct DocInfo {
std::string title; // 文档标题
std::string content; // 文档内容
std::string url; // 文档 URL
int doc_id; // 文档 ID
} DocInfo;
1.2 倒排索引结构
倒排索引记录关键词与文档 ID 的映射关系,并包含权重信息。一个关键词可能对应多个文档,形成所谓的'倒排拉链'。
// 倒排索引元素定义
struct InvertedElem {
int doc_id; // 文档 ID
std::string word;// 关键词
int weight; // 权重
};
typedef std::vector<InvertedElem> InvertedList;
2. 核心类设计与单例模式
2.1 成员变量规划
正排索引使用 std::vector,因为文档 ID 天然适合作为下标,访问效率高且节省空间。倒排索引使用 std::unordered_map,通过哈希表实现关键词到文档列表的快速映射。
private:
// 正排索引:Vector 下标即文档 ID
std::vector<DocInfo> forward_index;
// 倒排索引:哈希表映射关键词
std::unordered_map<std::string, InvertedList> inverted_index;
2.2 单例模式实现
为了保证全局逻辑统一并减少资源浪费(如内存占用和 IO 开销),索引管理器采用单例模式。同时,为了支持多线程环境下的安全访问,需要禁用拷贝构造和赋值运算符,并使用互斥锁保护实例初始化过程。
这里采用了双重检查锁定(Double-Checked Locking)机制,在进入锁之前和之后各判断一次 instance 是否为空,以防止高并发场景下的重复创建问题。
private:
Index() {};
( Index&) = ;
Index& =( Index&) = ;
Index* instance;
std::mutex log;
:
~();
{
(instance == ) {
log.();
(instance == ) {
instance = ();
}
log.();
}
instance;
}


