久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Solr:文本分析

 折騰plus難受 2017-01-20

文本分析時(shí)搜索引擎的核心工作之一,,對(duì)文本包含許多處理步驟,比如:分詞,、大寫轉(zhuǎn)小寫,、詞干化、同義詞轉(zhuǎn)化等,。簡(jiǎn)單的說,,文本分析就說將一個(gè)文本字段的值轉(zhuǎn)為一個(gè)一個(gè)的token,然后被保存到Lucene的索引結(jié)構(gòu)中被將來搜索用,。當(dāng)然,,文本分析不僅在建立索引時(shí)有用,在查詢時(shí)對(duì)對(duì)所輸入的查詢串也一樣可以進(jìn)行文本分析,。在 Solr Schema設(shè)計(jì) 中我們介紹了許多Solr中的字段類型,,其中最重要的是solr.TextField,這個(gè)類型可以進(jìn)行分析器配置來進(jìn)行文本分析,。

接下來我們先來說說什么是分析器,。

分析器

一個(gè)分析器可以檢查字段的文本信息,并且產(chǎn)生一個(gè) token 流,。
分析器是 schema.xml 中元素的一個(gè)子元素,,通常使用中,只有 solr.TextField 類型的字段會(huì)專門制定一個(gè)分析器,。最簡(jiǎn)單配置一個(gè)分析器的方式是使用<analyzer>元素,,制定這個(gè)元素的 class 屬性為一個(gè)完整的 Java 類名。這些類名必須源自 org.apache.lucene.analysis.Analyzer ,。
<fieldType name="nametext" class="solr.TextField">
  <analyzer class="org.apache.lucene.analysis.WhitespaceAnalyzer"/>
</fieldType>
在這個(gè)例子中,,WhitespaceAnalyzer 這個(gè)類負(fù)責(zé)分析文本字段的內(nèi)容并且產(chǎn)生出正確的 tokens,。如果只是簡(jiǎn)單的文本,例如“this is a pig",,像這樣的一個(gè)分析器的類足可以應(yīng)付了,,但是我們經(jīng)常需要對(duì)字段內(nèi)容做復(fù)雜的分析,這就需要把分析作為多個(gè)獨(dú)立的簡(jiǎn)單步驟來進(jìn)行處理了,。
以下是處理復(fù)雜分析的示例,,在<analyzer> 元素(不是類屬性)下添加分詞器和過濾器的工廠類:
復(fù)制代碼
<fieldType name="nametext" class="solr.TextField">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.StopFilterFactory"/>
  </analyzer>
</fieldType>
復(fù)制代碼
需要說明的話solr.前綴的包,其實(shí)是指向 org.apache.solr.analysis 這個(gè)包
在這個(gè)例子中,,在 <analyzer> 元素沒有指定分析器的類,,而是一系列的類共同承擔(dān)一個(gè)字段的分析器。文本首先傳到列表的第一個(gè)元素(solr.StandardTokenizerFactory),,然后再依次執(zhí)行filter,。簡(jiǎn)單的說就是經(jīng)過Tokenizer分詞之后,再繼續(xù)處理,,比如全轉(zhuǎn)成小寫,、時(shí)態(tài)處理、去掉語氣詞等,,產(chǎn)生出來的tokens 作為 terms 在字段的索引和查詢時(shí)使用,。

現(xiàn)在我們來看下Solr示例Schema配置中的text_en_splitting字段類型的定義,,看看它用了哪些分析組件。

復(fù)制代碼
    <!-- A text field with defaults appropriate for English, plus
   aggressive word-splitting and autophrase features enabled.
   This field is just like text_en, except it adds
   WordDelimiterFilter to enable splitting and matching of
   words on case-change, alpha numeric boundaries, and
   non-alphanumeric chars.  This means certain compound word
   cases will work, for example query "wi fi" will match
   document "WiFi" or "wi-fi".
        -->
    <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
      <analyzer type="index">
     <!--<charFilter class="solr.MappingCharFilterFactory"  mapping="mapping-ISOLatin1Accent.txt"/>-->
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <!-- in this example, we will only use synonyms at query time
        <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
        -->
        <!-- Case insensitive stop word removal.
        -->
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
    </fieldType>
復(fù)制代碼

Type屬性可以指定為index或是query值,,分別表示是索引時(shí)用的分析器,,和查詢時(shí)所用的分析器,。如果在索引和查詢時(shí)使用相同的分析器,你可以不指定type屬性值,。

分析器的配置中可以選用一個(gè)或多個(gè)字符過濾器(character filter),,字符過濾器是對(duì)原始文本進(jìn)行字符流級(jí)別的操作。它通??梢杂糜诖笮戅D(zhuǎn)化,,去除字母上標(biāo)等等。在字符過濾器之后是分詞器(Tokenizer),,它是必須要配置的,。分析器會(huì)使用分詞器將字符流切分成詞元(Token)系列,通常用在空格處切分這種簡(jiǎn)單的算法,。后面的步驟是可選的,,比如token過濾器(Token Filter)會(huì)對(duì)token進(jìn)行許多種操作,最后產(chǎn)生的詞元會(huì)被稱為詞(Term),,即用于Lucene實(shí)際索引和查詢的單位,。

最后,,我有必須對(duì)autoGeneratePhraseQueries布爾屬性補(bǔ)充兩句,,這個(gè)屬性只能用于文本域。如果在查詢文本分析時(shí)產(chǎn)生了多個(gè)詞元,,比如Wi-Fi分詞為WiFi,,那么默認(rèn)情況下它們只是兩個(gè)不同的搜索詞,它們沒有位置上的關(guān)系,。但如果autoGeneratePhraseQueries被設(shè)置,,那么這兩個(gè)詞元就構(gòu)造了一個(gè)詞組查詢,即“WiFi”,,所以索引中“WiFi”必須相鄰才能被查詢到,。在新Solr版本中,默認(rèn)它被設(shè)置為false,。我不建議使用它,。

在Admin上對(duì)字段進(jìn)行分析

在我們深入特定分析組件的細(xì)節(jié)之前,有必要去熟悉Solr的分析頁面,,它是一個(gè)很好的實(shí)驗(yàn)和查錯(cuò)工具,絕對(duì)不容錯(cuò)過,。你將會(huì)用它來驗(yàn)證不同的分析配置,,來找到你最想要的效果,,你還可以用它來找到你認(rèn)為應(yīng)該會(huì)匹配的查詢?yōu)槭裁礇]有匹配。在Solr的管理頁面,,你可以看到一個(gè)名為[Analysis]的鏈接,,你進(jìn)入后,會(huì)看到下面的界面,。

 

界面上的第一個(gè)選項(xiàng)是必選的,,你可選擇直接通過字段類型名稱來選擇類型,你也可以間接地通過一個(gè)字段的名字來選擇自端類型,。在上面的示例中,我選擇了title字段

通過Schema Browser可以看到這個(gè)字段類型是 text_general

 

點(diǎn)擊灰色的 text_general,,可以看到這個(gè)字段的分析器中定義的分詞器和過濾器

接下來,你可以分析索引或是查詢文本,,也可以兩者同時(shí)分析,。你需要輸入些文本到文本框中以進(jìn)行分析,。將字段值放到Index文本框中,將查詢文本放入Query文本框中,點(diǎn)擊Analyze按鈕看到一下文本處理結(jié)果,,因?yàn)檫€沒有中文處理,,所以中文都被一個(gè)字一個(gè)字的分開處理了。

 

你可以選中verbose output來查看處理的詳細(xì)信息,,我希望你能自己試一下,。

上圖中每一行表示分析器處理鏈上的每一步的處理結(jié)果。比如第三個(gè)分析組件是LowerCaseFilter,,它的處理結(jié)果就在第三行,。前面的ST/SF/LCF應(yīng)該是分詞器和過濾器的簡(jiǎn)稱。

下面我們接著來詳細(xì)看看有哪些分詞器和過濾器吧,。

Character Filter

字符過濾器在<charFilter>元素中定義,,它是對(duì)字符流進(jìn)行處理。字符過濾器種類不多,。這個(gè)特性只有下面第一個(gè)介紹的比較常見,。

  • MappingCharFilterFactory它將一個(gè)字符(或字符串)映射到另一個(gè),也可以映射為空,。換言之,,它是一個(gè)查找-替換的功能。在mapping屬性中你可以指定一個(gè)配置文件,。Solr的示例配置中包括了兩個(gè)有用的映射配置文件:
    1. mapping-FoldToASCII.txt:一個(gè)豐富的將non-ASCII轉(zhuǎn)化成ASCII的映射。如果想了解字符映射更多的細(xì)節(jié),,可以閱讀這個(gè)文件頂部的注釋,。這個(gè)字符過濾器有一個(gè)類似的詞元過濾器ASCIIFoldFilterFactory,這個(gè)詞元過濾器運(yùn)行速度更快,,建議使用它,。
    2. maping-ISOLatinAccent.txt:一個(gè)更小的映射文件子集,它只能將ISO Latin1上標(biāo)映射,。FoldToASCII內(nèi)容更豐富,,所以不建議使用這個(gè)配置。
  • HTMLStripCharFilterFactory它用于HTMLXML,,它不要求它們格式完全正確,。本質(zhì)上它是移除所有的標(biāo)記,只留下文本內(nèi)容,。移除腳本內(nèi)容和格式元素,。轉(zhuǎn)義過的特殊字符被還原(比如&),。
  • PatternReplaceCharFilterFactory根據(jù)pattern屬性中的正則表達(dá)式進(jìn)行查找,并根據(jù)replacement屬性中的值進(jìn)行替換,。它的實(shí)現(xiàn)需要一個(gè)緩沖區(qū)容器,,默認(rèn)設(shè)置為10000個(gè)字符,可以通過maxBlockChars進(jìn)行配置,。分詞器和詞元過濾器中也有正則表達(dá)式組件,。所以你應(yīng)該只在會(huì)影響分詞的影響下使用它,比如對(duì)空格進(jìn)行處理,。

Tokenization

分詞器在<tokenizer>元素中定義,,它將一個(gè)字符流切分成詞元序列,大部分它會(huì)去除不重要的符號(hào),,比如空字符和連接符號(hào),。

一個(gè)分析器有且只應(yīng)有一個(gè)分詞器,你可選的分詞器如下:

  • KeywordTokenizerFactory:這個(gè)分詞器不進(jìn)行任何分詞,!整個(gè)字符流變?yōu)閱蝹€(gè)詞元,。String域類型也有類似的效果,但是它不能配置文本分析的其它處理組件,,比如大小寫轉(zhuǎn)換,。任何用于排序和大部分Faceting功能的索引域,這個(gè)索引域只有能一個(gè)原始域值中的一個(gè)詞元,。
  • WhitespaceTokenizerFactory:文本由空字符切分(即,,空格,Tab,,換行),。
  • StandardTokenizerFactory:它是一個(gè)對(duì)大部分西歐語言通常的分詞器。它從空白符和其它Unicode標(biāo)準(zhǔn)中的詞分隔符處進(jìn)行切分,??瞻追头指舴麜?huì)被移除。連字符也被認(rèn)為是詞的分隔符,,這使得它不適合與WordDelimiterFilter一起用,。
  • UAX29URLEmailTokenizer:它表現(xiàn)的與StandardTokenizer相似,但它多了一個(gè)識(shí)別e-mail,,URL并將它們視為單個(gè)詞元的特性,。
  • ClassicTokenizerFactory:(曾經(jīng)的StandardTokenizer)它是一個(gè)英語的通用分詞器。對(duì)英語來說,,它優(yōu)于StandardTokenizer,。它可以識(shí)別有點(diǎn)號(hào)的縮寫詞,比如I.B.M.。如果詞元中包含數(shù)字它不會(huì)在連字符處分詞,,并可以將Email地址和主機(jī)名視為單個(gè)詞元,。并且ClassicFilter詞元過濾器經(jīng)常與這個(gè)分詞器配合使用。ClassicFilter會(huì)移除縮寫詞中的點(diǎn)號(hào),,并將單引號(hào)(英語中的所有格)去除,。它只能與ClassicTokenizer一起使用。
  • LetterTokenizerFactory:這個(gè)分詞器將相鄰的字母(由Unicode定義)都視為一個(gè)詞元,,并忽略其它字符,。
  • LowerCaseTokenizerFactory:這個(gè)分詞器功能上等同于LetterTokenizer加上LowerCaseFilter,但它運(yùn)行更快,。
  • PatternTokenizerFactory:這個(gè)基于正則表達(dá)式的分詞器可以以下面兩種方式工作:
    1. 通過一個(gè)指定模式切分文本,,例如你要切分一個(gè)用分號(hào)分隔的列表,你可以寫:<tokenizer class="solr.PatternTokenizerFactory" pattern=";*" />.
    2. 只選擇匹配的一個(gè)子集作為詞元,。比如:<tokenizer class="solr.PatternTokenizerFactory" pattern="\'([^\']+)\'" group="1" />,。組屬性指定匹配的哪個(gè)組將被視為詞元。如果你輸入的文本是aaa ‘bbb’ ‘ccc’,,那么詞元就是bbbccc,。
  • PathHierachyTokenizerFactory:這是一個(gè)可配置的分詞器,它只處理以單個(gè)字符分隔的字符串,,比如文件路徑和域名,。它在實(shí)現(xiàn)層次Faceting中很有用,或是可以過濾以某些路徑下的文件,。比如輸入字符串是/usr/local/apache會(huì)被分詞為三個(gè)詞元:/usr,,/usr/local/usr/local/apache,。這個(gè)分詞器有下面四個(gè)選項(xiàng):
    1. Delimiter:分隔字符:默認(rèn)為/
    2. Replace:將分隔字符替換為另一字符(可選)
    3. Reverse:布爾值表明是否層次是從右邊開始,,比如主機(jī)名,默認(rèn):false,。
    4. Skip:忽略開頭的多少個(gè)詞元,,默認(rèn)為0.
  • WikipediaTokenizerFactory:一個(gè)用于Mediawiki語法(它用于wikipedia)的實(shí)驗(yàn)性質(zhì)的分詞器。

還有用于其它語言的分詞器,,比如中文和俄語,還有ICUTokenizer會(huì)檢測(cè)語言,。另外NGramtokenizer會(huì)在后面討論,。可以在http://wiki./solr/AnalyzersTokenizersTokenFilters中找到更多內(nèi)容,。

WordDelimiterFilter

它也許不是一個(gè)正式的分詞器,,但是這個(gè)名為WordDeilimiterFilter的詞元過濾器本質(zhì)上是一個(gè)分詞器。

<filter class="solr.WordDelimiterFilterFactory"

generateWordParts="1" generateNumberParts="catenateWords="1" catenateNumbers="1"

catenateAll="0" splitOnCaseChange="1"/>

 上面并沒有給出所有的選項(xiàng),,這個(gè)過濾器可以通過多種配置指定如切分和連接合成詞,,并有多種定義合成詞的方法,。這個(gè)過濾器通常與WhitespaceTokenizer配合,而不是StandardTokenizer,。這個(gè)過濾器的配置中1是設(shè)置,,0是重置。

  WordDelimiterFilter先通過配置選項(xiàng)中的定義切分詞元

  • 詞間的分隔符切分:Agile-Me切為Agile,,Me
  • 字母和數(shù)據(jù)間的切分SD500切為SD,,500(如果設(shè)置splitOnNumerics
  • 忽略任何分隔符:hello,Agile-Me切為hello, Agile,Me
  • 移除所有格’sDavid’s切為Divid(如果設(shè)置stemEnglishPocessive
  • 在小寫到大小時(shí)切分:Agile-Me切為agile,me(如果設(shè)置splitOnCaseChange

此時(shí),如果下面的選項(xiàng)沒有設(shè)置,,上面這些切分后的詞都要被過濾掉,。因?yàn)槟J(rèn)下面的選項(xiàng)設(shè)置為false,你一般至少要設(shè)置下面其中一項(xiàng),。

  • 如果設(shè)置generateWordParts或是generateNumberParts,,那么全是字母或是全是數(shù)字的詞元就會(huì)不被過濾。他們還會(huì)受到連接選項(xiàng)的進(jìn)一步影響,。
  • 連接多個(gè)全字母的詞元,,設(shè)置catenateWords(比如wi-fi連接為wifi)。如果generateWordParts設(shè)置了,,這個(gè)例子還是會(huì)產(chǎn)生wifi,,反過來不成立。catenateNumbers工作方式也是相似的,。catenateAll會(huì)考慮連接所有的詞到一起,。
  • 要保留原始的詞,設(shè)置preserveOriginal,。

下面是一個(gè)對(duì)上面選項(xiàng)的解釋的例子:

WiFi-802.11b 切為 Wi,Fi,WiFi,802,11,80211,b,WiFi80211b, WiFi-802.11b

 

Stemming

詞干化是去除詞尾變化或是有時(shí)將派生詞變回它們的詞干——基本形的過程,。比如,一種詞干化算法可能會(huì)RidingRides轉(zhuǎn)化為Ride,。詞干化有助于提高結(jié)果召回率,,但是會(huì)對(duì)準(zhǔn)確率造成負(fù)影響。如果你是處理普通文本,,你用詞干化會(huì)提高你的搜索質(zhì)量,。但是如果你要處理的文本都是名詞,比如在MusicBrainz中的藝術(shù)家名字,,那么深度的詞干化可能會(huì)影響結(jié)果,。如果你想提高搜索的準(zhǔn)確率,并且不降低完整率,,那么你可以考慮將數(shù)據(jù)索引到兩個(gè)域,,其中一個(gè)進(jìn)行詞干化,另一個(gè)不進(jìn)行詞干化,在搜索時(shí)查找這兩個(gè)域,。

大多詞干器產(chǎn)生的詞干化的詞元都不再是一個(gè)拼寫合法的單詞,,比如Bunnies會(huì)轉(zhuǎn)化為Bunni,而不是Bunny,,Quote轉(zhuǎn)化為Quot,,你可以在Solr的文本分析頁面看到這些結(jié)果。如果在索引和查找時(shí)都進(jìn)行詞干化,,那么是不會(huì)影響搜索的,。但是一個(gè)域詞干化之后,就無法進(jìn)行拼寫檢查,,通配符匹配,,或是輸入提示,因?yàn)檫@些特性要直接用索引中的詞,。

下面是一些適用于英文的詞干器:

  • SnowballPorterFilterFactory:這個(gè)詞干器允許選擇多種詞干器算法,,這些詞干器算法是由一個(gè)名為Snowball的程序產(chǎn)生的。你可以在language屬性中指定你要選擇的詞干器,。指定為English會(huì)使用Porter2算法,,它比原生的Porter的算法有一點(diǎn)點(diǎn)改進(jìn)。指定為Lovins會(huì)使用Lovins算法,,它比起Porter有一些改進(jìn),,但是運(yùn)行速度太慢。
  • PorterStemFIlterFactory:它是原生的英語Porter算法,,它比SnowBall的速度快一倍,。
  • KStemFilterFactory:這個(gè)英語詞干器沒有Porter算法激進(jìn)。也就是在很多Porter算法認(rèn)為應(yīng)該詞干化的時(shí)候,,KSterm會(huì)選擇不進(jìn)行詞干化,。我建議使用它為默認(rèn)的英語詞干器。
  • EnglishMinimalStemFilterFactory:它是一個(gè)簡(jiǎn)單的詞干器,,只處理典型的復(fù)數(shù)形式,。不同于多數(shù)的詞干器,它詞干化的詞元是拼寫合法的單詞,,它們是單數(shù)形式的,。它的好處是使用這個(gè)詞干器的域可以進(jìn)行普通的搜索,還可以進(jìn)行搜索提示,。

Correcting and augmenting stemming

上面提到的詞干器都是使用算法進(jìn)行詞干化,,而不是通過詞庫(kù)進(jìn)行詞干化。語言中有許多的拼寫規(guī)則,,所以算法型的詞干器是很難做到完美的,有時(shí)在不應(yīng)該進(jìn)行詞干化的時(shí)候,也進(jìn)行了詞干化,。

如果你發(fā)現(xiàn)了一些不應(yīng)該進(jìn)行詞干化的詞,,你可以先使用KeywordMarkerFilter詞干器,并在它的protected屬性中指定不需要詞干化的詞元文件,,文件中一行一個(gè)詞元,。還有ignoreCase布爾選項(xiàng)。一些詞干器有或以前有protected屬性有相似的功能,,但這種老的方式不再建議使用,。

如果你需要指定一些特定的單詞如何被詞干化,就先使用StemmerOverrideFilter,。它的dictionary屬性可以指定一個(gè)在conf目錄下的UTF-8編碼的文件,,文件中每行兩個(gè)詞元,用tab分隔,,前面的是輸入詞元,,后面的是詞干化后的詞元。它也有ignoreCase布爾選項(xiàng),。這個(gè)過濾器會(huì)跳過KeywordMarkerFilter標(biāo)記過的詞元,,并且它會(huì)標(biāo)記它替換過的詞元,以使后面的詞干器不再處理它們,。

下面是三個(gè)詞干器鏈在分析器中配置的示例:

<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />

<filter class="solr.StemmerOverrideFilterFactory" dictionary="stemdict.txt" />

<filter class="solr.PorterStemFilterFactory" />

 

Synonyms

進(jìn)行同義詞處理的目的是很好理解的,,在搜索時(shí)搜索所用的關(guān)鍵詞可能本身并不匹配文檔中的任何一個(gè)詞,但文檔中有這個(gè)搜索關(guān)鍵詞的同義詞,,但一般來講你還是想匹配這個(gè)文檔的,。當(dāng)然,同義詞并一定不是按字典意義上同義詞,,它們可以是你應(yīng)該中特定領(lǐng)域中的同義詞,。

 這下一個(gè)同義詞的分析器配置:

<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt"  ignoreCase="true" expand="true"/>

synonyms的屬性值是在conf目錄下的一個(gè)文件。設(shè)置ignoreCasetrue在查找同義詞時(shí)忽略大小寫,。

在我們討論expand選項(xiàng)前,,我們考慮一個(gè)例子。同義詞文件是一行行的,。下面是一個(gè)顯式映射的例子,,映射用=>符號(hào)表示:

i-pod, i pod =>ipod

這表示如果在輸入詞元流中如果發(fā)現(xiàn)i-pod(一個(gè)詞元)或是i pod(兩個(gè)詞元),都會(huì)替換為ipod,。替換的同義詞也可以是多個(gè)詞元,。逗號(hào)是分隔多個(gè)同義詞之間的分隔符,同義詞的詞元間用空格分隔,。如果你要實(shí)現(xiàn)自定義的不用空格分隔的格式,,有一個(gè)tokenizerFactory屬性,,但它極少被使用。

你也可能看到配置文件里是這樣的格式:

ipod, i-pod, i pod

 配置文件里沒有=>符號(hào),,它的意義由expand參數(shù)來決定,,如果expandtrue,它會(huì)被解釋為下面的顯式映射:

ipod, i-pod, i pod =>ipod, i-pod, i pod

如果expand設(shè)置為false,,它就變?yōu)橄旅娴娘@式映射,,第一個(gè)同義詞為替換同義詞:

ipod, i-pod, i pod =>ipod

 在多行中指定多個(gè)詞替換為共一同義詞是允許的。如果一個(gè)源同義詞已經(jīng)被規(guī)則替換了,,另一個(gè)規(guī)則替換這個(gè)替換后詞,,則這兩個(gè)規(guī)則可以合并。

Index-time versus query-time, and to expand or not

如果你要進(jìn)行同義詞擴(kuò)展,,你可以在索引時(shí)或是查詢時(shí)進(jìn)行同義處理,。但不要在索引和查詢時(shí)都處理,這樣處理會(huì)得到正確的結(jié)果,,但是會(huì)減慢處理速度,。我建議在索引時(shí)進(jìn)行擴(kuò)展,因?yàn)樵诓樵儠r(shí)進(jìn)行會(huì)有下面的問題:

  • 一個(gè)源同義詞包含多個(gè)詞元(比如:i pod)不會(huì)在查詢時(shí)被查詢時(shí)被識(shí)別,,因?yàn)椴樵兘馕銎鲿?huì)在分析器處理之前就對(duì)空格進(jìn)行切分,。
  • 如果被匹配的一個(gè)同義詞在所有文檔中很少出現(xiàn),那么Lucene打分算法中的IDF值會(huì)很高,,這會(huì)使得得分不準(zhǔn)確,。
  • 前綴,通配符查詢不會(huì)進(jìn)行文本分析,,所以不會(huì)匹配同義詞,。

但是任何在索引時(shí)進(jìn)行的分文本處理都是不靈活的。因?yàn)槿绻淖兞送x詞則需要完全重建索引才能看到效果,。并且,,如果在索引時(shí)進(jìn)行擴(kuò)展,索引會(huì)變大,,如果你使用WordNet類似的同義詞規(guī)則,,可能索引大到你不能接受,所以你在同義詞擴(kuò)展規(guī)則上應(yīng)該選擇一個(gè)合理的度,,但是我通常還是建議在索引時(shí)擴(kuò)展,。

你也許可以采用一種混合策略。比如,,你有一個(gè)很大的索引,,所以你不想對(duì)它經(jīng)常重建,但是你需要使新的同義詞迅速生效,,所以你可以將新的同義詞在查詢時(shí)和索引時(shí)都使用,。當(dāng)全量索引重建完成后,,你可以清空查詢同義詞文件。也許你喜歡查詢時(shí)進(jìn)行同義詞處理,,但你無法處理個(gè)別同義詞有空格的情況,,你可以在索引時(shí)處理這些個(gè)別的同義詞。

Stop Words

StopFilterFactory是一個(gè)簡(jiǎn)單的過濾器,,它是過濾掉在配置中指定的文件中的停詞(stop words),這個(gè)文件在conf目錄下,,可以指定忽略大小寫,。

<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>

如果文檔中有大量無意義的詞,比如“the”,,“a”,,它們會(huì)使索引變大,并在使用短語查詢時(shí)降低查詢速度,。一個(gè)簡(jiǎn)單的方法是將這些詞經(jīng)常出現(xiàn)的域中過濾掉,,在包含多于一句(sentence)的內(nèi)容的域中可以考慮這種作法,但是如果把停詞過濾后,,就無法對(duì)停詞進(jìn)行查詢了,。所以如果你要使用,應(yīng)該在索引和查詢分析器鏈中都使用,。這通常是可以接受的,,但是在搜索“To be or not to be”這種句子時(shí),就會(huì)有問題,。對(duì)停詞理想的做法是不要去過濾它們,,以后介紹CommonGramsFilterFactory來解決這個(gè)問題。

Solr自帶了一個(gè)不錯(cuò)的英語停詞集合,。如果你在索引非英語的文本,,你要用自己指定停詞。要確定你索引中有哪些詞經(jīng)常出現(xiàn),,可以從Solr管理界面點(diǎn)擊進(jìn)入SCHEMA BROWSER,。你的字段列表會(huì)在左邊顯示,如果這個(gè)列表沒有立即出現(xiàn),,請(qǐng)耐心點(diǎn),,因?yàn)?span lang="EN-US">Solr要分析你索引里的數(shù)據(jù),所以對(duì)于較大的索引,,會(huì)有一定時(shí)間的延時(shí),。請(qǐng)選擇一個(gè)你知道包含有大量文本的域,你可以看到這個(gè)域的大量統(tǒng)計(jì),,包括出現(xiàn)頻率最高的10個(gè)詞,。

Phonetic sound-like analysis

語音轉(zhuǎn)換(phonetic translation)可以讓搜索進(jìn)行語音相似匹配,。語音轉(zhuǎn)化的過濾器在索引和查詢時(shí)都將單詞編碼為phoneme。有五種語音編碼算法:Caverphone,,DoubleMetaphone,,MetaphoneRefinedSoundexSoundex,。有趣的是,,DoubleMetaphone似乎是最好的選擇,即使是用在非英語文本上,。但也許你想通過實(shí)驗(yàn)來選擇算法,。RefinedSoundex聲稱是拼寫檢查應(yīng)用中最適合的算法。然而,,Solr當(dāng)前無法在它的拼寫檢查組件中使用語音分析,。

下面是在schema.xml里推薦使用的語音分析配置。

復(fù)制代碼
<!-- for phonetic (sounds-like) indexing -->

<fieldType name="phonetic" class="solr.TextField" positionIncrementGap="100" stored="false" multiValued="true">

  <analyzer>

    <tokenizer class="solr.WhitespaceTokenizerFactory"/>

    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="0" catenateWords="1" catenateNumbers="0" catenateAll="0"/>

    <filter class="solr.DoubleMetaphoneFilterFactory" inject="false" maxCodeLength="8"/>

  </analyzer>

</fieldType>
復(fù)制代碼

注意,,語音編碼內(nèi)部忽略大小寫,。

MusicBrainz Schema中,有一個(gè)名為a_phonetic使用這個(gè)域類型,,它的域值是通過copyField拷貝的Artist名字,。第四章你會(huì)學(xué)習(xí)到dismax查詢解析器可以讓你對(duì)不同的域賦不同的boost,同時(shí)查找這幾個(gè)域,。你可以不僅僅搜索a_name域,,你還可以用一個(gè)較低的boost來搜索a_phonenic域,這樣就可以進(jìn)行兼顧語音搜索了,。

Solr的分析管理頁面,,你可以看到這它將Smashing Pumpkins編碼為SMXNK|XMXNK PMPKNS|表示兩邊的詞元在同一位置)。編碼后的內(nèi)容看起來沒什么意義,,實(shí)際它是為比較相似語音的效率而設(shè)計(jì),。

上面配置示例中使用的DoubleMetaphoneFilterFactory分析過濾器,它有兩個(gè)選項(xiàng):

  • Inject:默認(rèn)設(shè)置為true,,為true會(huì)使原始的單詞直接通過過濾器,。這會(huì)影響其它的過濾器選項(xiàng),查詢,,還可能影響打分,。所以最好設(shè)置為false,并用另一個(gè)域來進(jìn)行語音索引,。
  • maxCodeLength:最大的語音編碼長(zhǎng)度,。它通常設(shè)置為4。更長(zhǎng)的編碼會(huì)被截?cái)?。只?span lang="EN-US">DoubleMetaphone支持這個(gè)選項(xiàng),。

如果要使用其它四個(gè)語音編碼算法,,你必須用這個(gè)過濾器:

<filter class="solr.PhoneticFilterFactory" encoder="RefinedSoundex" inject="false"/>

其中encoder屬性值是第一段中的幾個(gè)算法之一。

Substring indexing and wildcards

通常,,文本索引技術(shù)用來查找整個(gè)單詞,,但是有時(shí)會(huì)查找一個(gè)索引單詞的子串,或是某些部分,。Solr支持通配符查詢(比如mus*ainz),,但是支持它需要在索引時(shí)過行一定的處理。

要理解Lucene在索引時(shí)內(nèi)部是如何支持通配符查詢是很有用的,。Lucene內(nèi)部會(huì)在已經(jīng)排序的詞中先查詢非通配符前綴(上例中的mus),。注意前綴的長(zhǎng)度與整個(gè)查詢的時(shí)間為指數(shù)關(guān)系,前綴越短,,查詢時(shí)間越長(zhǎng)。事實(shí)上Solr配置Lucene中不支持以通配符開頭的查詢,,就是因?yàn)樾实脑?。另外,詞干器,,語音過濾器,,和其它一些文本分析組件會(huì)影響這種查找。比如,,如果running被詞干化為run,,而runni*無法匹配。

ReversedWildcardFilter

Solr不支持通配符開頭的查詢,,除非你對(duì)文本進(jìn)行反向索引加上正向加載,,這樣做可以提高前綴很短的通配符查詢的效率。

下面的示例應(yīng)該放到索引文本分析鏈的最后:

<filter class="solr.ReversedWildcardFilterFactory" />

你可以在JavaDocs中了解一些提高效率的選項(xiàng),,但默認(rèn)的就很不錯(cuò):http://lucene./solr/api/org/apache/solr/analysis/ReversedWildcardFilterFactory.html

Solr不支持查詢中同時(shí)有配置符在開頭和結(jié)尾,,當(dāng)然這是出于性能的考慮。

N-grams

N-gram分析會(huì)根據(jù)配置中指定的子中最小最大長(zhǎng)度,,將一個(gè)詞的最小到最大的子串全部得到,,比如Tonight這個(gè)單詞,如果NGramFilterFactory配置中指定了minGramSize2,,maxGramSize5,,那么會(huì)產(chǎn)生下面的索引詞:(2-grams)To, on , ni, ig, gh, ht(3-grams)ton, oni, nig, ight, ght, (4-grams)toni, onig, nigh, ight, (5-grams)tonig,,onigh, night,。注意Tonight完整的詞不會(huì)產(chǎn)生,因?yàn)樵~的長(zhǎng)度不能超過maxGramSize,。N-Gram可以用作一個(gè)詞元過濾器,,也可以用作為分詞器NGramTokenizerFactory,,它會(huì)產(chǎn)生跨單詞的n-Gram

下是是使用n-grams匹配子串的推薦配置:

復(fù)制代碼
<fieldType name="nGram" class="solr.TextField" positionIncrementGap="100" stored="false" multiValued="true">

  <analyzer type="index">

    <tokenizer class="solr.StandardTokenizerFactory"/>

    <!-- potentially word delimiter, synonym filter, stop words, NOT stemming -->

    <filter class="solr.LowerCaseFilterFactory"/>

    <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="15"/>

  </analyzer>

  <analyzer type="query">

    <tokenizer class="solr.StandardTokenizerFactory"/>

    <!-- potentially word delimiter, synonym filter, stop words, NOT stemming -->

    <filter class="solr.LowerCaseFilterFactory"/>

  </analyzer>

</fieldType>
復(fù)制代碼

注意n-Gram只在索引時(shí)進(jìn)行,,gram的大小配置是根據(jù)你想進(jìn)行匹配子串的長(zhǎng)度而決定 的(示例中是最小是2,,最長(zhǎng)是15)。

N_gram分析的結(jié)果可以放到另一個(gè)用于匹配子串的域中,。用dismaxquery解析器支持搜索多個(gè)域,,在搜索匹配這個(gè)子串的域可以設(shè)置較小的boost

另一個(gè)變形的是EdgeNGramTokenizerFactoryEdgeNGramFilterFactory,,它會(huì)忽略輸入文本開頭或結(jié)尾的n-Gram,。對(duì)過濾器來說,輸入是一個(gè)詞,,對(duì)分詞器來說,,它是整個(gè)字符流。除了minGramSizemaxGramSize之后,,它還有一個(gè)side參數(shù),,可選值為frontback。如果只需要前綴匹配或是后綴匹配,,那邊EdgeNGram分析是你所需要的了,。

N-gram costs

n-Gram的代價(jià)很高,前面的例子中Tonight15個(gè)子串詞,,而普通的文本分析的結(jié)果一般只有一個(gè)詞,。這種轉(zhuǎn)換會(huì)產(chǎn)生很多詞,也就需要更長(zhǎng)的時(shí)間去索引,。以MusicBrainz Schema為例,,a_name域以普通方式索引并storeda_ngram域?qū)?span lang="EN-US">a_name中的值進(jìn)行n-Gram分析,,子串的長(zhǎng)度為2-15,。它不是一個(gè)stored域,因?yàn)?span lang="EN-US">Artist的名字已經(jīng)保存在a_name中了,。

a_name a_name + a_ngram

Increase

Indexing Time 46 seconds 479 seconds > 10x

Disk Size 11.7 MB 59.7 MB > 5x

Distinct Terms 203,431 1,288,720 > 6x

上表給出了只索引a_name和索引a_namea_ngram的統(tǒng)計(jì)信息,。注意索引時(shí)間增加了10倍,而索引大小增加了5倍,。注意,,這才只是一個(gè)域。

注意如果變大minGramSize的大小,,nGram的代價(jià)會(huì)小很多,。Edge nGraming也代價(jià)也會(huì)小,因?yàn)樗魂P(guān)心開頭或結(jié)尾的nGram?;?span lang="EN-US">nGram的分詞器無疑會(huì)比基于nGram的過濾器代碼要高,,因?yàn)榉衷~器將產(chǎn)生帶空格的詞,然而,,這種方式可以支持跨詞的通配符,。

Sorting Text

通常,搜索結(jié)果是由神奇的score偽字段進(jìn)行排序的,,但是有時(shí)候也會(huì)根據(jù)某個(gè)字段的值進(jìn)行排序,。除了對(duì)結(jié)果進(jìn)行排序,它還有許多的作用,,進(jìn)行區(qū)間查詢和對(duì)Facet結(jié)果進(jìn)行排序,。

MusicBrainz提供了對(duì)ArtistLable名稱進(jìn)行排序的功能。排序的版本會(huì)將原來的名字中的某些詞,,比如“The”移到最后,,用逗號(hào)分隔。我們將排序的名字域設(shè)置為indexed,,但不是stored,,因?yàn)槲覀円獙?duì)它進(jìn)行排序,但不進(jìn)行展示,,這與MusicBrainz所實(shí)現(xiàn)的有所不同。記住indexedstored默認(rèn)設(shè)置為true,。因?yàn)橛行┪谋痉治鼋M件會(huì)限制text域的排序功能,,所以在你的Schema中要用于排序的文本域應(yīng)該拷貝到另一個(gè)域中。copyField功能會(huì)很輕松地完成這個(gè)任務(wù),。String類型不進(jìn)行文本分析,,所以它對(duì)我們的MusicBrainz情況是非常適合的。這樣我們就支持了對(duì)Artist排序,,而沒有派生任何內(nèi)容,。

Miscellaneous token filters

Solr還包括許多其它的過濾器:

  • ClassicFilterFactory:它與ClassicTokenizer配置,它會(huì)移除縮寫詞中的點(diǎn)號(hào)和末尾的’s"I.B.M. cat's" => "IBM", "cat"
  • EnglishProcessiveFilterFactory:移除’s,。
  • TrimFilterFactory:移除開頭和結(jié)尾的空格,,這對(duì)于臟數(shù)據(jù)域進(jìn)行排序很有用。
  • LowerCaseFilterFactory:小寫化所有的文本,。如果你要用WordDelimeterFilterFactory中的大小寫轉(zhuǎn)換切分功能,,你就不要將這個(gè)過濾器放前面。
  • KeepWordFilterFactory:只保留指定配置文件中的詞:<filter class="solr.KeepWordFilterFactory" words="keepwords.txt" ignoreCase="true"/>       如果你想限制一個(gè)域的詞匯表,,你可以使用這個(gè)過濾器,。
  • LengthFilterFactory:過濾器會(huì)過濾掉配置長(zhǎng)度之間的詞:<filter class="solr.LengthFilterFactory" min="2" max="5" />
  • LimitTokenCountFilterFactory:限制域中最多有多少個(gè)詞元,數(shù)量由maxTokenCount屬性指定。Solrsolrconfig.xml中還有<maxFieldLength>設(shè)置,,它對(duì)所有域生效,,可以將它注釋掉,不限制域中的詞元個(gè)數(shù),。即使沒有強(qiáng)制限制,,你還要受Java內(nèi)存分配的限制,如果超過內(nèi)存分配限制,,就會(huì)拋出錯(cuò)誤,。
  • RemoveDuplicatestTokenFilterFactory:保存重復(fù)的詞不出現(xiàn)在同一位置。當(dāng)使用同義詞時(shí)這是可能發(fā)生的,。如果還要進(jìn)行其它的分本分析 ,,你應(yīng)該把這個(gè)過濾器放到最后。
  • ASCIIFoldingFilterFactory:參見前面的“Character filter”一節(jié)中的MappingCharFilterFactory,。
  • CapitalizationFilterFactory:根據(jù)你指定的規(guī)則大寫每個(gè)單詞,。你可以在http://lucene./solr/api/org/apache/solr/analysis/CapitalizationFilterFactory.html中了解更多內(nèi)容。
  • PatternReplaceFilterFactory:使用正則表達(dá)式查找替換,。比如:<filter class="solr.PatternReplaceFilterFactory" pattern=".*@(.*)" replacement="$1" replace="first" />  這個(gè)例子是處理e-mail地址域,,只取得地址中的域名。Replacement是正則表達(dá)式中的組,,但它也可以是一個(gè)字符串,。如果replace屬性設(shè)置為first,表示只替換第一個(gè)匹配內(nèi)容,。如果replace設(shè)置為all,,這也是默認(rèn)選項(xiàng),則替換全部,。
  • 實(shí)現(xiàn)你自己的過濾器:如果現(xiàn)有的過濾器無法滿足你的需求,。你可以打開Solr的代碼看一下里面是如何實(shí)現(xiàn)的。在你深入之前,,你看PatternReplaceFilterFactory的實(shí)現(xiàn)是如此簡(jiǎn)單,。作為一個(gè)初學(xué)者,可以看一下在本書提供的補(bǔ)充資料中schema.xml中的rType域類型,。
  • 還有其它各式各樣的Solr過濾器,,你可以在http://lucene./solr/api/org/apache/solr/analysis/TokenFilterFactory.html 中了解所有的過濾器。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多