1. 多個MUST的組合沒必要多說,就是交集html
2. MUST和SHOULD的組合。是在MUST搜出來的doc裏面,根據SHOULD的query進行打分。也就是說,SHOULD的query不會影響最終的HITS,只會提供打分依據。post
3. SHOULD的組合。若是最終的BooleanQuery只有SHOULD,那麼搜出來的doc至少要知足一個SHOULD的query,也就是說是邏輯OR。ui
那麼在下面這段代碼中,問題就出現了:spa
代碼的本意是在baseQuery的基礎上和geoQuery作一個交集htm
public Map<String, Query> buildGeoQuery(Query baseQuery) {
Map<String, Query> queryMap = new HashMap<String, Query>();
for(String key : localHashMap.keySet()) {
List<String> hashValues = localHashMap.get(key);
BooleanQuery bq = new BooleanQuery();
bq.add(baseQuery, Occur.MUST);
if(hashValues.size() == 1) {
TermQuery hashQuery = new TermQuery(new Term(Constants.FIELD_SEARCH_HASH, hashValues.get(0)));
bq.add(hashQuery, Occur.MUST);
}
else if(hashValues.size() > 1) {
for(String value : hashValues) {
TermQuery hashQuery = new TermQuery(new Term(Constants.FIELD_SEARCH_HASH, value));
bq.add(hashQuery, Occur.SHOULD);
}
}
queryMap.put(key, bq);
}
return queryMap;
}blog
在第三個用紅色標註的語句中,本意是對多個geohash query作邏輯OR的操做(使用了should),可是因爲最開始的basequery是以MUST關鍵字加入的,那麼這些個geohash query只作爲打分依據,而不是必須出現的,這樣就會致使有一些額外的doc被搜出來。排序
正確的作法應該是用一個獨立的GeoQuery來把geohash termquery組合起來,最後將geoQuery和baseQuery用Occur.MUST組合token
===============================================================================ip
lucene3.0中BooleanQuery 實現與或的複合搜索 .
BooleanClause用於表示布爾查詢子句關係的類,包 括:BooleanClause.Occur.MUST,BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.SHOULD。 必須包含,不能包含,能夠包含三種.有如下6種組合:
1.MUST和MUST:取得連個查詢子句的交集。
2.MUST和MUST_NOT:表示查詢結果中不能包含MUST_NOT所對應得查詢子句的檢索結果。
3.SHOULD與MUST_NOT:連用時,功能同MUST和MUST_NOT。
4.SHOULD與MUST連用時,結果爲MUST子句的檢索結果,可是SHOULD可影響排序。
5.SHOULD與SHOULD:表示「或」關係,最終檢索結果爲全部檢索子句的並集。
6.MUST_NOT和MUST_NOT:無心義,檢索無結果。get
====================================================================================
在輸入要搜索的關鍵字時,Lucene是這樣處理的:
+a +b:搜索同時包含a又包含b的結果集
a b:搜索包含a或包含b的結果集
+a -b:搜索包含a不包含b的結果集
也就是以下結論:
a & b => +a +b
a || b => a b
a !b => +a -b
那在代碼中該如何來構造這種與或非的關係呢?
通常用BooleanQuery來構造。
//構造BooleanQuery
QueryParser parser = new QueryParser("content", analyzer);
BooleanQuery bquery = new BooleanQuery();
TokenStream ts = analyzer.TokenStream(null, new StringReader(querystring));
Lucene.Net.Analysis.Token token;
while ((token = ts.Next()) != null)
{
Query query = parser.Parse(token.TermText());
bquery.Add(query, BooleanClause.Occur.MUST);
}
//構造完成
IndexSearcher searcher = new IndexSearcher("IndexDirectory");
//Query query = parser.Parse(querystring);
//輸出咱們要查看的表達式
Console.WriteLine(bquery.ToString());
Hits hits = searcher.Search(bquery);
for (int i = 0; i < hits.Length(); i++)
{
Document doc = hits.Doc(i);
Console.WriteLine(doc.Get("title"));
}
}
其中,bquery.Add(query, BooleanClause.Occur.MUST);MUST構造出「與」的關係
構造「或」關係:bquery.Add(query, BooleanClause.Occur.SHOULD);
構造「非」關係:bquery.Add(query, BooleanClause.Occur.MUST_NOT);