目錄
1.項(xiàng)目相關(guān)背景
2.搜索引擎的相關(guān)宏觀原理
3.搜索引擎技術(shù)棧和項(xiàng)目環(huán)境
4.正排索引 && 倒排索引--搜索引擎原理
5.編寫數(shù)據(jù)去標(biāo)簽與數(shù)據(jù)清洗的模塊 -- parser.hpp
去標(biāo)簽
編寫parser(將文件去標(biāo)簽)
編寫EnumFile函數(shù)
編寫ParseFile函數(shù)
解析三大部分:
編寫SaveFile函數(shù)
6.建立索引--編寫index.hpp模塊
構(gòu)建正排索引
構(gòu)建倒排索引
jieba分詞
編寫倒排索引
7.編寫搜索searcher
8.編寫http_server模塊
測(cè)試
引入cpp-httplib庫(kù)
利用scl源升級(jí)gcc
安裝cpp-httplib
基本使用測(cè)試
正式編寫httplib對(duì)應(yīng)的調(diào)用
9.編寫前端模塊
vscode環(huán)境配置
編碼
編寫html
編寫css
編寫js
1.項(xiàng)目相關(guān)背景
- boost的官網(wǎng)是沒有站內(nèi)搜索的,需要我們自己做一個(gè)
現(xiàn)在市面上已經(jīng)有很多搜索引擎,比如百度,搜狗360等等這些公司已經(jīng)做好的搜索引擎。事實(shí)上這些公司寫出來的項(xiàng)目都是非常大型的項(xiàng)目,其中的技術(shù)門檻非常高。我們自己實(shí)現(xiàn)一個(gè)完整的搜索引擎是不可能的。但是我們可以寫一個(gè)簡(jiǎn)單的搜索引擎,也就是站內(nèi)搜索,也就是我們今天要寫的項(xiàng)目?jī)?nèi)容。
像百度這種全網(wǎng)型搜索是非常大型的,它需要將全網(wǎng)的信息搜集起來,并將它們保存起來建立相關(guān)的索引模塊,并且還要根據(jù)優(yōu)先度對(duì)他們進(jìn)行排序,這是一個(gè)非常大的工作。
那么站內(nèi)搜索:它的搜索方式是更垂直的,站內(nèi)的各個(gè)信息相關(guān)性更強(qiáng)。
2.搜索引擎的相關(guān)宏觀原理
前端通過客戶端瀏覽器通過GET方法向后端服務(wù)器進(jìn)行http請(qǐng)求,通過輸入關(guān)鍵詞/短語分詞來進(jìn)行查找。后端模塊首先將官網(wǎng)html文檔導(dǎo)入到磁盤中,方便我們進(jìn)行去標(biāo)簽的清晰標(biāo)簽工作,里面只保存我們需要讓用戶看到的標(biāo)題,摘要以及url;然后將清洗好的數(shù)據(jù)建立正派索引和倒排索引。再其次進(jìn)行搜索功能建立,對(duì)輸入的關(guān)鍵詞進(jìn)行分詞,然后查找倒排找到文檔 id,然后通過他們不同的權(quán)重進(jìn)行從高到低的排列,最后通過httplib將后端代碼和前端交互。
3.搜索引擎技術(shù)棧和項(xiàng)目環(huán)境
技術(shù)棧:C/C++,C++11,STL庫(kù),標(biāo)準(zhǔn)庫(kù)Boost(主要處理一些文件),jsoncpp(序列化反序列化),cppjieba(搜索內(nèi)容分詞)cpphttp-lib(幫我們寫http),html5,css,js,jQuery,Ajax.
項(xiàng)目環(huán)境:Centos7云服務(wù)器,vim/gcc(g++),vs2013/vscode(前端)
4.正排索引 && 倒排索引--搜索引擎原理
假設(shè)這里有兩個(gè)文檔:
- 文檔1:雷軍買了四斤小米
- 文檔2:雷軍發(fā)布了小米手機(jī)
正排索引:就是從文檔ID找到文檔內(nèi)容(找到文檔關(guān)鍵字)
文檔ID | 文檔內(nèi)容 |
1 | 雷軍買了四斤小米 |
2 | 雷軍發(fā)布了小米手機(jī) |
我們?cè)賮砜匆粋€(gè)概念:
分詞:對(duì)目標(biāo)文檔進(jìn)行分詞(為了方便建立倒排索引和查找)
- 對(duì)文檔1進(jìn)行分詞:雷軍買了四斤小米:雷軍/買/四斤/小米/四斤小米(四斤小米可以作為一個(gè)分詞整體)
- 對(duì)文檔2進(jìn)行分詞:雷軍發(fā)布了小米手機(jī):雷軍/發(fā)布/小米/手機(jī)/小米手機(jī)
停止詞:了,的,嗎,a,the,一般我們?cè)俜衷~的時(shí)候可以不考慮。
倒排索引:根據(jù)文檔內(nèi)容,分詞,整理不重復(fù)的各個(gè)關(guān)鍵字,找到對(duì)應(yīng)聯(lián)系文檔ID的方案(也就是根據(jù)分詞找到文檔ID)
關(guān)鍵字 (具有唯一性:兩個(gè)文檔都出現(xiàn),但是我們只保留一份) |
文檔ID,weight() |
雷軍 | 文檔1,文檔2 |
買 | 文檔1 |
四斤 | 文檔1 |
小米 | 文檔1,文檔2 |
四斤小米 | 文檔1 |
發(fā)布 | 文檔2 |
手機(jī) | 文檔2 |
小米手機(jī) | 文檔2 |
注意:文檔ID中可以包括weight權(quán)重,這樣就形成了競(jìng)價(jià)排名,對(duì)權(quán)重高的排名在前面,顯示在前面。
就比如說你要搜索小米,那么那個(gè)文檔搜索出來的小米權(quán)重高呢,哪個(gè)就排在前面
模擬一次查找的過程:
用戶輸入:小米->倒排索引中查找->提取處文檔ID(1,2)->根據(jù)正排索引->找到文檔的內(nèi)容->將title標(biāo)題+conent(desc)文檔描述+url網(wǎng)址信息=文檔結(jié)果進(jìn)行摘要->構(gòu)建相應(yīng)結(jié)果
5.編寫數(shù)據(jù)去標(biāo)簽與數(shù)據(jù)清洗的模塊 -- parser.hpp
boost官網(wǎng):Boost C++ Libraries
因?yàn)閎oost網(wǎng)站沒有站內(nèi)搜索引擎,所以我們要寫一個(gè)。boost官網(wǎng)中已經(jīng)給我們提供了字典排序,我們將它下載下來,下載最新的即可。下載好后我們?cè)谠品?wù)器上創(chuàng)建一個(gè)目錄boost_searcher,并將我們剛剛下載好的文件導(dǎo)入進(jìn)去,通過rz -E +文件即可導(dǎo)入。
上傳好之后通過tar xzf boost_1_78_0.tar.gz解壓,在boost_searcher中形成了一個(gè)目錄,這個(gè)目錄中保存了所有boost內(nèi)容。
實(shí)際上我們用到的boost庫(kù)中的文件內(nèi)容,大部分來自于doc下的html文件,html目錄中的文件就是各種boost組件對(duì)應(yīng)的組件內(nèi)容。也就是我們只需要html下的文件:
/boost_searcher/boost_1_78_0/doc/html
我們將html中的內(nèi)容復(fù)制到我們新建的目錄data/input下,這個(gè)input放的就是boost的數(shù)據(jù)源,也就是我們8000個(gè)數(shù)據(jù)源。這里的內(nèi)容就可以來構(gòu)建我們的站內(nèi)網(wǎng)頁(yè)信息了。
[wjy@VM-24-9-centos boost_searcher]$ cp -rf boost_1_78_0/doc/html/* data/input/
去標(biāo)簽
在boost_sercher目錄下創(chuàng)建parser.cc文件,用來將原始數(shù)據(jù) 變成 去標(biāo)簽之后的數(shù)據(jù)
我們隨便打開一個(gè)文件看一下里面的源文件
[wjy@VM-24-9-centos input]$ nano process.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chapter?30.?Boost.Process</title>
<link rel="stylesheet" href="../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="libraries.html" title="Part?I.?The Boost C++ Libraries (BoostBook Subset)">
<link rel="prev" href="poly_collection/acknowledgments.html" title="Acknowledgments">
<link rel="next" href="boost_process/concepts.html" title="Concepts">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../boost.png"></td>
<td align="center"><a href="../../index.html">Home</a></td>
<td align="center"><a href="../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a >People</a></td>
<td align="center"><a >FAQ</a></td>
<td align="center"><a href="../../more/index.htm">More</a></td>
</tr></table>
<hr>
<>是html的標(biāo)簽,這些標(biāo)簽對(duì)我們搜索是沒有價(jià)值的,我們需要去除標(biāo)簽,一般標(biāo)簽都是成對(duì)出現(xiàn)的。比如<td align="center"><a href="../../index.html">Home</a></td>這一行只要在標(biāo)簽里的都是沒有用的,有用的只有Home。
所以我們要將數(shù)據(jù)清洗,清洗后的數(shù)據(jù)我們需要放在一個(gè)文件中,我們將清洗后的數(shù)據(jù)放在data目錄下的raw_html中
[wjy@VM-24-9-centos data]$ mkdir raw_html
[wjy@VM-24-9-centos data]$ ll
total 20
drwxrwxr-x 60 wjy wjy 16384 Jul 30 19:29 input //這里放的是html原始文檔
drwxrwxr-x 2 wjy wjy 4096 Jul 30 19:53 raw_html //這里放的是去標(biāo)簽之后干凈的文檔
查看input目錄下,html文檔有多少個(gè)
[wjy@VM-24-9-centos input]$ ls -Rl | grep -E '*.html' | wc -l
8141
目標(biāo):把每個(gè)文檔都去標(biāo)簽,然后寫入到同一個(gè)文件中,每個(gè)文檔內(nèi)容不需要任何\n換行!文檔和文檔之間用\n來進(jìn)行區(qū)分。
XXXXXXXXXXX\3YYYYYYYYYYY\3ZZZZZZZZZZZ\3
為什么是\3?在下面的ascii表中我們可以看到,其中有些字符叫做控制字符,是不可顯示的;有些字符是打印字符,現(xiàn)在很多文檔中字符都是打印字符,其中\(zhòng)3對(duì)應(yīng)的是^C,它是控制字符,是不會(huì)顯示在文檔中。這樣就不會(huì)污染文檔中的顯示字符。文檔中顯示的只有顯示字符。當(dāng)然你也可以用\4,\5這些不可顯示字符作為分隔符。
編寫parser(將文件去標(biāo)簽)
我么要將input源文件去標(biāo)簽都放到raw_html中,所以要在raw_html目錄下創(chuàng)建一個(gè)文檔raw.txt,專門用來放這8000多個(gè)有效字符串。
[wjy@VM-24-9-centos raw_html]$ touch raw.txt
[wjy@VM-24-9-centos raw_html]$ ll
total 0
-rw-rw-r-- 1 wjy wjy 0 Jul 30 20:33 raw.txt
在去標(biāo)簽之前我們需要將input中的原文檔讀取出來,讀取文檔之前需要獲取文檔的路徑,所以我們定義一個(gè)字符串,因?yàn)閐ata/input和perser.cc在一個(gè)目錄下,所以定義的路徑字符串是const std::string src_path="data/input/";有讀取文檔目錄的路徑,就有接收文檔路徑,data/raw_html/raw.txt,將它定義成一個(gè)字符串變量output。
文章來源:http://www.zghlxwxcb.cn/news/detail-428626.html
下面我們來編寫parser.cc的大體框架,我們需要將文檔中的一大堆字符串都分成各個(gè)文檔,分成8000多個(gè)文檔,放入vector中;然后對(duì)每個(gè)vector中的string文檔進(jìn)行解析,去標(biāo)簽解析成我們需要的title標(biāo)題,文檔內(nèi)容content,還有url文檔網(wǎng)址,我們將它寫成一個(gè)結(jié)構(gòu)體。然后將這些解析好的string再放入raw.txt文件下,也即是我們定義的outputstring路徑下。文章來源地址http://www.zghlxwxcb.cn/news/detail-428626.html
[wjy@VM-24-9-centos boost_searcher]$ cat parser.cc
到了這里,關(guān)于Boost搜索引擎項(xiàng)目的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!