Boost搜索引擎

目录

一·功能和框架

二·技术栈与项目环境

三·具体代码结构

​编辑 四·项目背景

 五·项目宏观原理

 六·数据去标签模块

七·建立索引模块

建立正排索引

 建立倒排索引

倒排原理解析

 八·建立搜索模块

将index设置为单例模式

九·网络模块

十·前端模块


一·功能和框架

功能:实现boost文档站内搜索。通过输入关键字,将与关键字有关的网页按文档权值大小,罗列出来。前端显示包括,标题,摘要,网址~

框架:

二·技术栈与项目环境

 技术栈:

c/c++、c++11、STL、准标准库boost、Jsoncpp、cppjieba、cpp-httplib

项目环境:

Linux CentOS 7云服务器、vim/gcc(g++)/Makefile、vscode 

 

三·具体代码结构

 四·项目背景

        项目与日常搜索搜索网站不同,如百度,360,搜狗。此搜索引擎只支持boost库1.78版本站内搜索

boost库:

        

 我们平时在网上搜索的内容都以三个内容返回给我们;标题,摘要,网页url

我们在数据清理阶段只需要对boost/html下的文件标题,摘要,url进行处理即可

 五·项目宏观原理

 六·数据去标签模块

我们下载到linux中的boost1.78文档中有好多东西是我们不需要的

 以上<title></title>和划线的都是不需要的我们将这一些去掉并将这些文档内容按每个文档:

文档1:标题\3摘要\3/url\n

文档2:标题\3摘要\3/url\n

...

以此这样排列好放在一个特定目录下方便我们进行检索

在进行原始文件的处理时用到了boost库开发的工具就掠过吧~

去标签代码:parser.cc

//判断文件是否为html后缀文件,是的话就放在一个集合进行统一处理
bool EnumFile(const std::string &src_path, std::vector<std::string> *files_list);
//解析文件将文件标题,目录,URl按照我们上面说的方式整理放在一个集合。
bool ParseHtml(const std::vector<std::string> &files_list, std::vector<DocInfo_t> *results);
//将处理好的html文件(已经处理好的去标签,数据清洗完的。统一放在output文件里。每个文件按\n分割)
bool SaveHtml(const std::vector<DocInfo_t> &results, const std::string &output);
int main()
{
  std::vector<std::string> files_list;
  //第一步: 递归式的把每个html文件名带路径,保存到files_list中,方便后期进行一个一个的文件进行读取
  if (!EnumFile(src_path, &files_list))
  {
    std::cerr << "enum file name error!" << std::endl;
    return 1;
  }
  // 第二步: 按照files_list读取每个文件的内容,并进行解析
  std::vector<DocInfo_t> results;
  if (!ParseHtml(files_list, &results))
  {
    std::cerr << "parse html error" << std::endl;
    return 2;
  }

  // //第三步: 把解析完毕的各个文件内容,写入到output,按照\3作为每个文档的分割符
  if (!SaveHtml(results, output))
  {
    std::cerr << "sava html error" << std::endl;
    return 3;
  }

  return 0;
}

bool EnumFile(const std::string &src_path, std::vector<std::string> *files_list)
{
  namespace fs = boost::filesystem;
  fs::path root_path(src_path);

  //判断路径是否存在,不存在,就没有必要再往后走了
  if (!fs::exists(root_path))
  {
    std::cerr << src_path << " not exists" << std::endl;
    return false;
  }

  //定义一个空的迭代器,用来进行判断递归结束
  fs::recursive_directory_iterator end;
  for (fs::recursive_directory_iterator iter(root_path); iter != end; iter++)
  {
    //判断文件是否是普通文件,html都是普通文件
    if (!fs::is_regular_file(*iter))
    {
      continue;
    }
    if (iter->path().extension() != ".html")
    { //判断文件路径名的后缀是否符合要求
      continue;
    }
    std::cout << "debug: " << iter->path().string() << std::endl;
    //当前的路径一定是一个合法的,以.html结束的普通网页文件
    files_list->push_back(iter->path().string()); //将所有带路径的html保存在files_list,方便后续进行文本分析
  }

  return true;
}

static bool ParseTitle(const std::string &file, std::string *title)
{
  std::size_t begin = file.find("<title>");
  if (begin == std::string::npos)
  {
    return false;
  }
  std::size_t end = file.find("</title>");
  if (end == std::string::npos)
  {
    return false;
  }

  begin += std::string("<title>").size();

  if (begin > end)
  {
    return false;
  }
  *title = file.substr(begin, end - begin);
  return true;
}

static bool ParseContent(const std::string &file, std::string *content)
{
  //去标签,基于一个简易的状态机
  enum status
  {
    LABLE,
    CONTENT
  };

  enum status s = LABLE;
  for (char c : file)
  {
    switch (s)
    {
    case LABLE:
      if (c == '>')
        s = CONTENT;
      break;
    case CONTENT:
      if (c == '<')
        s = LABLE;
      else
      {
        //我们不想保留原始文件中的\n,因为我们想用\n作为html解析之后文本的分隔符
        if (c == '\n')
          c = ' ';
        content->push_back(c);
      }
      break;
    default:
      break;
    }
  }

  return true;
}

static bool ParseUrl(const std::string &file_path, std::string *url)
{
  std::string url_head = "https://www.boost.org/doc/libs/1_78_0/doc/html";
  std::string url_tail = file_path.substr(src_path.size());

  *url = url_head + url_tail;
  return true;
}

// // for debug
static void ShowDo
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值