Solr複雜查詢一:函式查詢

雲山之巔發表於2020-04-17

一.簡介

  Solr的函式可以動態計算每個文件的值,而不是返回在索引階段對應欄位的靜態數值集。函式查詢是一類特殊的查詢,它可以像關鍵詞一樣新增到查詢中,對所有文件進行匹配並返回它們的函式計算值作為文件得分。使用函式查詢,函式計算結果將用於修改相關度得分或用於搜尋結果的排序。在應用程式層,函式計算的結果可以作為一個動態欄位新增到每個文件。函式也可以巢狀,即一個函式的輸出可以作為另一個函式的輸入,函式允許巢狀任意多層。

二.函式語法

  Solr的標準函式語法首先定義一個函式名,後面緊跟一對括號,括號中包括零個、一個或多個輸入引數,引數之間以逗號分隔:

  functionName()

  functionName(input1)

  funtionName(input1,...inputN)

  以下內容都可以作為 函式的輸入:

  1.常量。例如:100,“Hello world”等

  2.欄位。例如:fieldName,field(fieldName)

  3.另一個函式。例如:functionName(...)

  4.替代引數。例如:q={!func}min($f1,$f2)&f1=sqrt(popularity)&f2=1

  Solr將文件中每個輸入引數的型別定義為函式,初看可能會對此感到困惑。絕大多數函式遵循標準的函式語法,但常量函式、欄位函式和替代引數是簡化語法的特例。常量函式的語法就是常量值本身;欄位函式的語法是欄位的名稱,可以選擇性地在函式中包含field命名;替代引數的語法是$parameter,其表示URL請求的查詢字串引數。除此之外,其它函式都遵循標準的函式語法。

  由於函式的所有 輸入可以看成函式本身【即使輸入的是常量函式】,標準的函式語法可以在概念上簡化為functionName(function1,...,functionN)。

  假設文件中的fieldContainingNumber欄位包含值-99,則會出現以下情況:

  

  不難看出,每個函式可以容易地將欄位函式置換為常量函式或者其他標準函式。雖然每個例子中計算輸入引數的命令和方法不同,但都返回了-99和2之間的最大值。將一個函式輸入作為另一個函式的引數的好處是,以有趣的方式組合函式來實現複雜的計算。

  並不是所有的函式都接受相同型別的輸入引數。一些函式將常量值輸入轉變為字串,另一些函式則將其轉變為整數或者浮點數。假設fieldContainingString賦予hello值,如下所示:

  

  strdist函式基於一種特殊的演算法【由第三個引數定義,edit表示文字型別】來計算兩個字串的相似度。如果在此函式中輸入了錯誤的型別,會出現以下結果:

  

  該函式會自動型別轉換,在此是把數值型轉換為字串。很多時候這種轉換是不可能的【例如:字串轉數值】,這種情況下,通常會收到Solr異常提醒。需要明確一點,雖然函式巢狀語法是通用的,但並不是所有的函式都可以組合成功。

  Solr的函式通用性使得它們可以在Solr的各種核心功能上使用。函式可以影響相關度,可以過濾結果,可以用於排序,也可以對文件附加返回的函式值,甚至可以用在分面上。

三.函式的搜尋

  在Solr中執行典型的關鍵詞搜尋時,每個關鍵詞會在倒排文件中查詢一遍,通過計算相關度得分來決定每個文件與關鍵詞的匹配程度。查詢並不侷限於詞項本身,也可以在查詢中插入函式 ,將其視為另一個關鍵詞。如下:

  

  該查詢執行布林搜尋的關鍵詞為United States,France,和President,以及一個返回值為1~100區間值的函式,這個函式用來衡量匹配文件的新舊程度【文件越新,返回值越高】。此查詢有如下三個方面需要特別注意:

  1.語法_val_:value用來將一個查詢函式【巢狀recip和ord函式】作為一個詞項插入到使用者主查詢語句中。

  2.函式查詢預設匹配所有文件。在上面例子中查詢被限制在包含三個詞項的所有文件中,函式查詢作為額外的詞項並沒有改變查詢匹配的文件結果數。

  3.一個查詢的相關度評分是查詢中每個詞項相關度得分的總和。上面提到的三個詞項都會得到各自基於tf-idf【詞頻-逆文件頻率】相似度計算的相關度得分,然而函式查詢的得分是函式自身的取值。

  _val_的目的是讓越新的文件相關度得分越高。具體而言,最新文件的相關度得分將獲得100的加分,最舊文件的相關度得分將獲得1的加分,其餘文件根據其新舊程度獲得1~100之間的加分。注意,每個文件的最後得分會經過規範化處理,因此不會看到實際的1~100分加到每個文件的最後得分中,只會看到越新的文件排名提升越多。如果 從查詢中移除函式,Solr的搜尋結果排序會發生變化。

  在查詢中掛接函式

  上面提到的_val_:"functionName(...)"語法,可以像關鍵詞那樣插入到查詢的任何位置。Solr包含一個函式查詢解析器,通過本地引數{!func}functionName(...)進行呼叫。兩種方式可以實現相同的功能:將函式的值作為一個詞項新增到查詢中,它的相關度得分就是函式本身的值。因此,一下語句是等價的。

  

  通過向查詢新增函式,可以調整與查詢匹配的文件相關度得分,這個做法似乎很有用。事實上,如果想要通過函式計算來過濾某個適合結果區間以外的結果,函式查詢就不那麼有效了。所幸,Solr提供了函式區間查詢解析器來解決此類需求。

  frange查詢解析器

  如果需要對搜尋結果進行過濾,只留下函式計算產生特定值的文件,可以選擇函式區間解析器。frange過濾器執行一個特定的函式查詢,然後過濾掉函式值落在最低值和最高值範圍之外的文件。例如:

  

 frange查詢解析器過濾了總價格在10~15區間之外的那些文件,上限和下限通過本地引數l【最低】和u【最高】來定義。上限和下限是預設的,如果只想匹配包含特定值的文件,可以將l和u的值設為同一值。另外,上限值和下限值的設定是可選的,沒有強制要求同時設定上下限。如有需要,frange查詢中的本地引數incll【包含下限】和inclu【包含上限】可設定為false,這樣可以過濾出不在區間範圍內的文件。

四.以欄位形式返回函式

  所有的函式輸入,包括常量和欄位,在函式查詢語法中都可視為函式本身。既然如此,函式和欄位最終都會返回一個值,因此在Solr中其他一些地方中用函式替代欄位是可行的。

  事實上,不僅可以計算每個文件對應的函式值,也可以將文件的計算值當作偽欄位返回。例如:

  

  搜尋結果如下:

  

   Solr搜尋結果向欄位列表請求增加一個函式,會將一個新的欄位新增到文件中。這並不是儲存在索引中的真實欄位,但會像儲存欄位一樣返回到文件。返回到文件中的偽欄位名稱是計算函式值的語法,這非常不好,因此,需要為返回值的偽欄位名稱自定義別名。如下:

  

  冒號之前是偽欄位的名稱,冒號之後是計算偽欄位值額函式。這讓偽欄位可以像真實欄位一樣返回函式值。事實上,動態計算的偽欄位也可以覆蓋一個真實欄位。這樣的用例需要在不同用例中的同一個欄位上返回不同的值,例如,基於使用者訪問許可權清空欄位,或為不同地域提供各種版本的內容翻譯來修改欄位值。在返回搜尋結果之前,函式可以操作任何欄位的取值。函式不僅可以修改返回的文件欄位,還可以改變返回文件的排序。

五.函式排序

  函式的排序語法與欄位的排序語法的唯一不同之處在於,整個函式語法【引用引數包含全函式語法】取代了欄位名稱:

  

  這個請求將根據之前計算的總價格進行排序【升序】,如果價格相同,則按照文件得分降序排序。

六.Solr的可用函式集

  Solr的函式主要分為4類:資料轉換函式、數學函式、相關度函式和布林函式。

  1.資料轉換函式

    Solr中最常見的函式是將資料從一種格式轉換成另一種格式的函式。例如:map(x, min, max, target):如果x落在最小值與最大值之間,則使用x替換target的值。

  常用資料轉換函式如下:

  

  2.數學函式

  

  

  

  3.相關度函式

    Solr的相關度得分預設使用DefaultSimilarity類計算。這個類使用了來自搜尋索引及查詢術語的多種統計資料,以便識別出與查詢最佳匹配的文件。Solr的相關度函式可以返回單獨的統計資料供選用。所有關鍵的相關度統計資料都包含在內,例如常見的tf-idf。

  

  例如:

  

  4.距離函式

    有時計算兩個值直接的距離很有用,可能是地球上兩個座標點的地理距離,也有可能是兩個點或者向量的幾何距離,甚至是兩個字串之間的字元距離。如下:

  

  5.布林函式

  

相關文章