搜尋引擎 lucene

2021-08-13 17:00:44 字數 3869 閱讀 5306

lucene簡介

搜尋引擎的幾個概念--倒排

倒排索引(inverted index),也稱為反向索引,是搜尋引擎中最常見的資料結構,幾乎所有的搜尋引擎都會使用到倒排索引,它將文件中的詞作為關鍵字,

建立詞與文件的對映關係,通過對倒排索引的檢索,可以根據詞快速獲取包含這個詞的文件列表,這對於搜尋引擎來說至關重要。

分詞,又稱為切詞,就是將句子或者段落進行切割,從中提取出包含固定語義的詞。對於英語來說,語言的基本單位就是單詞,因此,分詞特別容易,只需要根據空格/符號/段落進行分割,並且排除停止詞(stop word),提取詞幹,即可完成,但是對於中文來說,要將一段文字準確的切分成乙個個詞,就不那麼容易了,中文是以字為最小單位,多個字連在一起才能構成乙個表達具體含義的詞,中文的句子和段落都有乙個明顯的標點符號分割,唯獨詞沒有乙個形式上的分割符,因此,對於支援中文搜尋的搜尋引擎來說,需要乙個合適的中文分詞工具,以便建立倒排索引。 :提取詞幹是西方語言特有的處理步驟,比如英文中的單詞有單複數的變形,-ing和-ed的變形,但是在搜尋引擎中,應該當做同乙個詞。

停止詞(stop word),在英語中包含了a、the、and這樣使用頻率很高的詞,如果這些詞都被建到索引中進行索引的話,搜尋引擎就沒有任何意義了,因為幾乎所有的文件都會包含這些詞,對於中文來說也是如此,中文裡面也有一些出現頻率很高的詞,如「在」、「這」、「了」、「於」等等,這些詞沒有具體含義,區分度低,搜尋引擎對這些詞進行索引沒有任何意義,因此,停止詞需要被忽略掉。

排序,當輸入乙個關鍵字進行搜尋時,可能會命中許多文件,搜尋引擎給使用者的價值就是快速的找到需要的文件,

因此,需要將相關度更大的內

容排在前面,以便使用者能夠更快的篩選出有價值的內容,這時就需要有適當的排序演算法。一般來說,命中標題的文件將比命中內容的文件有更高的相

關性,命中多次的文件比命中一次的文件有更高的相關性,商業化的搜尋引擎的排序規則十分複雜,搜尋結果的排序融入了廣告、競價排名等因素,由

於牽涉的利益廣泛,一般屬於核心的商業機密。

文件(document),在lucene的定義中,文件是一系列域(field)的組合,而文件的域則代表一系列與文件相關的內容,與資料庫表的記錄的概念

有點類似,一行記錄所包含的字段對應的就是文件的域,舉例來說,乙個文件比如老師的個人資訊,可能包括年齡、身高、性別、個人簡介等等內容。

域(field),索引的每個文件中都包含乙個或者多個不同名稱的域,每個域都包含了域的名稱和域對應的值,並且,域還可以是不同的型別,如字串、整型、浮點型等。

查詢(query),最基本的查詢可能是一系列term的條件組合,稱為termquery,但也有可能是短語查詢(phrasequery)、字首查詢

(prefixquery)、範圍查詢(包括termrangequery、numericrangequery等)等等。

分詞器(analyzer),文件在被索引之前,需要經過分詞器處理,以提取關鍵的語義單元,建立索引,並剔除無用的資訊,如停止詞等,以提高查

詢的準確性。中文分詞與西文分詞區別在於,中文對於詞的提取更為複雜。

常用的中文分詞器包括一元分詞、二元分詞、詞庫分詞等等。

一元分詞,即將給定的字串以乙個字為單位進行切割分詞,這種分詞方式較為明顯的缺陷就是語義不准,如「上海」兩個字被切割成「上」、

「海」,但是包含「上海」、「海上」的文件都會命中。

二元分詞比一元分詞更符合中文的習慣,因為中文的大部分詞彙都是兩個字,但是問題依然存在。

詞庫分詞就是使用詞庫中定義的詞來對字串進行切分,這樣的好處是分詞更為準確,但是效率較n元分詞更低,且難以識別網際網路世界中層出

不窮的新興詞彙。

lucene索引構建過程

lucene索引的構建過程大致分為這樣幾個步驟,首先,通過指定的資料格式,將lucene的document傳遞給分詞器analyzer進行分詞,經過分詞器分詞之後,通過索引寫入工具indexwriter將索引寫入到指定的目錄。

lucene索引搜尋過程

索引的查詢,大概可以分為如下幾個步驟,首先,構建查詢的query,通過indexsearcher進行查詢,得到命中的topdocs,然後通過topdocs的scoredocs()方法,拿到scoredoc,通過scoredoc,得到對應的文件編號,indexsearcher通過文件編號,使用indexreader對指定目錄下的索引內容進行讀取,得到命中的文件返回。

索引優化

lucene的索引是由段(segment)組成的,每個段可能又包含多個索引檔案,每個段包含了乙個或者多個document,段結構使得lucene可以很好的支援增量索引,新增的document將被新增到新的索引段當中。但是,當越來越多的段被新增到索引當中,索引檔案也就越來越多,一般來說,作業系統對於程序開啟的檔案控制代碼數是有限的,當乙個程序開啟太多的檔案時,會丟擲too many open files異常,並且,執行搜尋任務時,lucene必須分別搜尋每

個段,然後將各個段的搜尋結果合併,這樣,查詢的效能就會降低。

全量索引重建

因為前面說到我們產生索引碎片,而這些索引碎片即使進行了碎片合併而減少碎片數,但是一旦當碎片達到一定大小後就不適合繼續進行合併,否則合併代價很大,所以我們無法避免的會因為碎片問題而導致更新實時性和查詢qps效能損耗問題。我們的解決的辦法就是通過一段時間對具體業務全部源資料進行一次構建全量索引dump工作,用構建好的新的全量主索引去替換原來老的主索引和磁碟索引,從而讓實時更新、搜尋服務效能恢復到最佳。

lucene的indexreader和indexwriter

lucene的indexreader和indexwriter具有隔離性:

 當indexreader.open開啟乙個索引的時候,相對於給當前索引進行了一次snapshot,此後的任何修改都不會被看到

 僅當indexreader.open開啟乙個索引後,才有可能看到從上次開啟後對索引的修改

 當indexwriter沒有呼叫commit的時候,其修改的內容是不能夠被看到的,哪怕indexreader被重新開啟

 欲使最新的修改被看到,一方面indexwriter需要commit,一方面indexreader重新開啟

實時更新

倒排索引是有一定的格式的,而這個格式一旦寫入是非常難以改變,那麼如何能夠增量建索引呢?lucene使用段這個概念解決了這個問題,對於每個已經生成的段,其倒排索引結構不會再改變,而增量新增的文件新增到新的段中,段之間在一定的時刻進行合併,從而形成新的倒排索引結構。

然而也正因為lucene的索引讀寫的隔離性,使得lucene的索引不夠實時,如果想lucene實時,則必須在新添文件後對indexwriter進行commit,在搜尋的時候indexreader需要重新的開啟,然而當索引在硬碟上的時候,尤其是索引非常大的時候,indexwriter的commit操作和indexreader的open操作都是非常慢的,根本達不到實時性的需要。

實時更新過程

實時更新過程

實時更新過程

搜尋引擎的分布式

使用solr的兩大優勢

1.支援schema構建索引

2.對複雜的動態的類sql的查詢條件的支援

3.solr並不完美,還有很多地方需要

搜尋引擎 lucene 例子

最近專案中要用到全文搜尋,所以在網上搜了下,找到了lucene 學習下 lucene是乙個很容易上手的搜尋引擎框架,傳統的搜尋引擎,涉及到爬蟲,也就是爬取網頁,然後對網頁進行加工,也就是索引,最後用於搜尋,lucene這個框架可以很方便的幫你做到後面兩個步驟,也就是索引和搜尋!本文嘗試通過乙個例子,...

搜尋引擎lucene入門程式示例

下面是我學習lucene3.4入門時按照lucene in action 第二版改寫的乙個例子。首先要匯入lucene core 3.4.0.jar包。package com.cn import org.apache.lucene.analysis.standard.standardanalyzer...

搜尋引擎 索引

正排索引 文件編號,單詞編號,單詞的數量,單詞出現的位置。倒排索引 1,單詞詞典,儲存單詞以及統計資訊,單詞在記錄表中的便宜,可常駐記憶體,用雜湊表儲存。2,記錄表,單詞對應的文件集合,記錄單詞出現的數目 位置。文件採用差分變長編碼。其中文件可按編號公升序排列 可利用差分編碼 也可按出現次數排列,可...