4.3 表達式
使用者搜尋,隻會輸入一個或幾個詞,也可能是一句話。輸入的語句是如何變成搜尋條件的上一篇已經略有提及。
4.3.1 觀察表達式
在研究表達式之前,一定要知道,任何一個Query都會對于一個表達式。不光可以通過Query構造表達式,還可以通過拼接字元串構造。這裡說的觀察表達式是指,用Query完成查詢語句後,用ToString()方法輸出Query的表達式。很簡單是吧,呵呵。
4.3.2 表達式的與或非
“與或非”讓我想起上學的時候學的門電路 ==#。先動手看看什麼是與或非。
先準備好代碼4.3.2.1,OK,現在測試。結果輸出:
搜尋詞:測試
結果:
content:"測 試"
測試系統
來測試
測試測
-----------------------------------
第三行,就是表達式。這個表達式不知道是什麼意思?輸入了“測試”這兩個字進行搜尋,怎麼會變成 “content:"測 試"”呢?可以看出,“測試”中間空了一個空格,還多了一個content。“測試”中間有空格不難了解,是分詞器對它進行拆分的結果。至于content,這個需要把目光轉到QueryParser類上去,在構造QueryParser類的時候,就加了這麼個參數。這個是表面要搜尋哪個字段。為了驗證這個想法,現在把“測試”換成英文“ab”,把content換成title.
也就是替換以下兩句:
List<string> list = new List<string>() { "ab" }; //在方法SearcherTest中
QueryParser parser = new QueryParser("title", analyzer); //在方法Searcher中
現在再測試一下:
搜尋詞:ab
title:ab
看到了,果然是這樣的。
現在把查詢的字段還是換成content,然後把關鍵字換成“真是”。
搜尋詞:真是
content:"真 是"
結果出來了,也印證了上面的想法。但是明明有一條記錄同時包含這兩個字了,為什麼沒有搜尋到呢?是不是加個空格就可以了呢?把“真的”變成“真 的”。再來試試。
搜尋詞:真 是
content:真 content:是
測試
真神奇,表達式變掉了,而且隻包含一個“是”但是沒有“真”的記錄也出來了。這表明什麼?這表明現在的語句就是或的關系,隻要滿足包含“是”或者包含“真”就可以搜尋到了。
但是我現在就想要搜尋同時包含兩個字的記錄怎麼辦呢?嘿嘿,在每個字前面加個“+”号試試。關鍵詞變成“+真 +是”看看結果:
搜尋詞:+真 +是
+content:真 +content:是
那現在我要搜尋包含“是”但是不包含“真”的結果,怎麼辦?試試這個語句“-真 +是”。
搜尋詞:-真 +是
-content:真 +content:是
與或非終于被我們折騰完了。
總結下關系就是:
a & b => +a +b
a || b => a b
a !b => +a -b
4.3.3 如何用Query構造與或非
Lucene.Net架構提供的Query也是可以完成與或非運算的,一般用BooleanQuery來構造。怎麼構造?現在對搜尋部分代碼進行變動,變成4.3.3.1。
測試:
構造出與的表達式了。把BooleanQuery的Add方法第二個參數換成BooleanClause.Occur.SHOULD,
bquery.Add(query, BooleanClause.Occur.SHOULD);
這個就是或:
而換成 bquery.Add(query, BooleanClause.Occur.MUST_NOT);這個就是非了:
-content:真 -content:是
4.3.4 其它特使符号
如果形容"+-"為Lucene.Net的運算符的話,那隻有這麼兩個也太單調了。實際上它還有其它運算符。
+-!():^[]{}~*?
上面的字元都是它的運算符号,這麼多運算符用起來很友善。但是也就出現另外一個問題。
什麼問題?下一節再講。