1. 程式人生 > >Lucene查詢方式總結

Lucene查詢方式總結

--------------------------------------------------
IndexReader的設計
--------------------------------------------------

IndexReader的建立需要消耗大量記憶體空間,
所以通過將IndexReader設計出屬性值,進行一次建立

整個專案週期就只有一個IndexReader

1.// IndexReader的設計

private static IndexReader reader = null;
2.在構造方法中對IndexReader進行初始化
// 建立indexReader
reader = IndexReader.open(directory);
3.建立getSearch()方法,返回IndexSearch
private static IndexSearcher getSearch() {
return new IndexSearcher(reader);
}
4.最後在使用IndexReader完畢後,只需要關閉IndexSearch
// 最後只需要關閉search

search.close();

PS:
因此此IndexReader屬於單例模式,在IndexReader過程中如果改變IndexWriter的索引,IndexReader所search出的資料將不會改變,除非重新構建一個新的IndexReader
程式碼優化:

// 優化

try {
	if (reader == null) {
	reader = IndexReader.open(directory);
	//reader = IndexReader.open(directory,false);  //不設定為只讀的reader
	} else {
	// 如果Index索引改變了將返回一個新的reader,否則將返回null
	IndexReader read = IndexReader.openIfChanged(reader);
	if (read != null) {
                //把原來的reader給close()掉
	reader.close();
	reader = read;
		}
	}
	return new IndexSearcher(reader);
	} catch (CorruptIndexException e) {
			e.printStackTrace();
} catch (IOException e) {
			e.printStackTrace();
}
	return null;




//因為此時Reader已經為全域性範圍,用reader也能刪除文件
/*
 * 使用reader刪除,會立即更新索引資訊(但不建議)
*/

// reader.deleteDocuments(new Term("id","1"));
// reader.close();
有時候整個專案週期中只有一個IndexWriter
這時候,IndexWriter就不能關閉
那麼怎麼提交呢?
使用IndexWriter.commit()方法提交對索引操作後的資料


--------------------------------------------------------
Directory的幾種操作方式
--------------------------------------------------------
FSDirectory.open()。。系統會根據具體執行環境使用最佳方式開啟一個Directory
new RAMDirectory()。。就是將索引儲存在記憶體中。好處:速度快。壞處:不能持久化
RAMDirectory(Directory dir)。也可以將一個持久化好的directory放入記憶體中。



-------------------------------------------------------
lucene的搜尋_TermRange等基本搜尋
-------------------------------------------------------
1.建立IndexSearch
/*
* 建立IndexSearch的方法
*/

	public IndexSearcher getSearch() {
		try {
			if (reader == null) {
				reader = IndexReader.open(directory);
			} else {
				IndexReader read = IndexReader.openIfChanged(reader);
				if (read != null) {
					reader.close();
					reader = read;
				}
			}
			return new IndexSearcher(reader);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}


2.查詢的幾種
======精確查詢:

IndexSearcher search = getSearch();
Query query = new TermQuery(new Term(field, name));
TopDocs tds = search.search(query, num);
for (ScoreDoc sdc : tds.scoreDocs) {
   Document doc = search.doc(sdc.doc);
}
search.close();


======基於字串的範圍查詢(TermRange)
// true表示閉區間

IndexSearcher search = getSearch();
Query query = new TermRangeQuery(field, start, end, true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);


======基於數字的範圍查詢(NumericRangeQuery.new...)
IndexSearcher search = getSearch(); 
// true表示閉區間
Query query = NumericRangeQuery.newIntRange(field, start, end,true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);



======PS:tds.totalHits是總記錄數,與我們傳入的num,沒有任何關係
eg:

   // 基於範圍的查詢(引數:傳入的field,開始字元,結束字元,顯示數目)
public void SearchByTermRange(String field, String start, String end,int num) {
		try {
			IndexSearcher search = getSearch();
			// 範圍查詢
			// true表示閉區間(是否包含開始字元和結束字元,預設為true)
			Query query = new TermRangeQuery(field, start, end, true, true);
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}






-----------------------------------------------------------------
lucene的搜尋_其他常用Query搜尋
-----------------------------------------------------------------
======字首搜尋(prefixquery)
Query query = new PrefixQuery(new Term(field, value));


======萬用字元搜尋(wildcardquery)
Query query = new WildcardQuery(new Term(field, value));
//使用方法
sutil.SearchByWildCard("name", "l*", 3);
在傳入的value中可以使用萬用字元? 和 * 
?表示匹配一個字元,*表示匹配任意多個字元。可以在任何位置使用。



=======可以連線多個條件(BooleanQuery)
BooleanQuery query = new BooleanQuery();
// Occur.Must表必須 
//Occur.SHOULD表示可有可無 
//Occur.MUST_NOT表示必須沒有
query.add(new TermQuery(new Term("name", "lili")), Occur.MUST);
query.add(new TermQuery(new Term("content", "hello")), Occur.MUST);


=======短語查詢(phrasequery)
PhraseQuery query = new PhraseQuery();
// setSlop()設定跳數,及兩個單詞之間有幾個單詞
query.setSlop(1);
// 設定field欄位,即哪兩個單詞
// 第一個term
query.add(new Term("content", "i"));
// 產生距離後的第二個term
query.add(new Term("content", "basketball"));


======模糊查詢(FuzzyQuery)

//會匹配有一個字元出錯的情況

Query query=new FuzzyQuery(new Term("name", "mirk"));



-------------------------------------------------------------
lucene的搜尋_基於QueryParser的搜尋
-------------------------------------------------------------
//基於字串操作
		public void SearchByQueryParse(Query query,int num){
			try {
				IndexSearcher search = getSearch();
				
				TopDocs tds = search.search(query, num);
				System.out.println("一共查詢了:" + tds.totalHits);
				for (ScoreDoc sdc : tds.scoreDocs) {
					Document doc = search.doc(sdc.doc);
					System.out.println(sdc.doc + doc.get("name") + "["
							+ doc.get("email") + "," + doc.get("id") + ","
							+ doc.get("attach") + "]");
				}
				search.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}


//使用query查詢(建立queryparser,再通過queryparser建立query)
                                // 1.建立Parse物件(設定預設搜尋域為content)
		QueryParser parse = new QueryParser(Version.LUCENE_35, "content",new StandardAnalyzer(Version.LUCENE_35));
		// 改變空格的預設操作(改為AND型)
		parse.setDefaultOperator(Operator.AND);
		// 開啟第一個字元的萬用字元匹配(*xxx,?xxx),預設關閉,因為效率比較低
		parse.setAllowLeadingWildcard(true);
		// 2.通過parse生成query(搜尋content域中包含有like的)
		Query query = parse.parse("like");
		// 能夠一直加條件(空格預設就是OR)
		query = parse.parse("basketball i");
		// 改變搜尋域(域:值)
		query = parse.parse("name:mark");
		// 同樣能進行*或?的萬用字元匹配(萬用字元預設不能放在首位)
		query = parse.parse("name:*i");
		// name中不包含mark,但是content中包含basketball(-和+必須放在域說明的前面)
		query = parse.parse("- name:mark + basketball");
		// id的1~3(TO表示一個閉區間,TO必須是大寫的)
		query = parse.parse("id:[1 TO 3]");
		// {}表示1~3的開區間匹配
		query = parse.parse("id:{1 TO 3}");
		// name域值是lili或mark,預設域值是game
		query = parse.parse("name:(lili OR mark) AND game");
		// 兩個‘’號表示短語匹配
		query = parse.parse("'i like basketball'");
		// 表示i basketball之間有一個單詞遺漏的匹配
		query = parse.parse("\"i basketball\"~1");
		// 加個~就能模糊查詢mark
		query = parse.parse("name:mirk~");
		// 沒有辦法匹配數字範圍(自己擴充套件parse)
		query = parse.parse("attach:[1 TO 3]");
		sutil.SearchByQueryParse(query, 5);




------------------------------------------------------------
簡單分頁搜尋

------------------------------------------------------------
Lucene通過再查詢的方式:將所有資料取出,再進行分段分頁
3.5以後使用的是searchAfter
//第一種分頁方式(通過取出全部資料,再通過start和end對資料進行分頁)

	public void searchPage(String query,int pageIndex,int pageSize) {
		try {
			Directory dir = FileIndexUtils.getDirectory();
			IndexSearcher searcher = getSearcher(dir);
			QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35));
			Query q = parser.parse(query);
			TopDocs tds = searcher.search(q, 500);
			ScoreDoc[] sds = tds.scoreDocs;
			int start = (pageIndex-1)*pageSize;
			int end = pageIndex*pageSize;
			for(int i=start;i<end;i++) {
				Document doc = searcher.doc(sds[i].doc);
				System.out.println(sds[i].doc+":"+doc.get("path")+"-->"+doc.get("filename"));
			}
			
			searcher.close();
		} catch (org.apache.lucene.queryParser.ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}




-----------------------------------------------------------
lucene的搜尋_基於searchAfter的實現(Lucene3.5之後)
-----------------------------------------------------------
/**
  * 根據頁碼和分頁大小獲取上一次的最後一個ScoreDoc
*/

private ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher) throws IOException {
		if(pageIndex==1)return null;//如果是第一頁就返回空
		int num = pageSize*(pageIndex-1);//獲取上一頁的數量
                                //每次只取上面所有的元素
		TopDocs tds = searcher.search(query, num);
		return tds.scoreDocs[num-1];
	}
	
	public void searchPageByAfter(String query,int pageIndex,int pageSize) {
		try {
			Directory dir = FileIndexUtils.getDirectory();
			IndexSearcher searcher = getSearcher(dir);
			QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35));
			Query q = parser.parse(query);
			//先獲取上一頁的最後一個元素
			ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher);
			//通過最後一個元素搜尋下頁的pageSize個元素
			TopDocs tds = searcher.searchAfter(lastSd,q, pageSize);
			for(ScoreDoc sd:tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc+":"+doc.get("path")+"-->"+doc.get("filename"));
			}
			searcher.close();
		} catch (org.apache.lucene.queryParser.ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

程式碼片段

package test.lucene.index;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

public class SearchUtil {
	/*
	 * 假設6個文件
	 */
	private String[] ids = { "1", "2", "3", "4", "5", "6" };
	private String[] emails = { "[email protected]", "[email protected]", "[email protected]",
			"[email protected]", "[email protected]", "[email protected]" };
	private String[] contents = { "hello boy,i like pingpang", "like boy",
			"xx bye i like swim", "hehe, i like basketball",
			"dd fsfs, i like movie", "hello xxx,i like game" };
	private int[] attachs = { 2, 3, 1, 4, 5, 5 };
	private String[] names = { "lili", "wangwu", "lisi", "jack", "tom", "mark" };
	// 設定加權map
	private Map<String, Float> scores = new HashMap<String, Float>();

	private Directory directory;
	private IndexReader reader;

	public SearchUtil() {
		directory = new RAMDirectory();
	}

	/*
	 * 新增索引
	 */
	public void index() {
		IndexWriter writer = null;
		try {

			writer = new IndexWriter(directory, new IndexWriterConfig(
					Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
			writer.deleteAll();
			// 建立documents
			Document document = null;
			for (int i = 0; i < ids.length; i++) {
				document = new Document();
				document.add(new Field("id", ids[i], Field.Store.YES,
						Field.Index.NOT_ANALYZED_NO_NORMS));
				document.add(new Field("email", emails[i], Field.Store.YES,
						Field.Index.NOT_ANALYZED)); // 不分詞
				document.add(new Field("content", contents[i], Field.Store.NO,
						Field.Index.ANALYZED));
				document.add(new Field("name", names[i], Field.Store.YES,
						Field.Index.NOT_ANALYZED));
				// 為數字新增索引
				document.add(new NumericField("attach", Field.Store.YES, true)
						.setIntValue(attachs[i]));
				/*
				 * document.setBoost(float) 設定評級
				 */
				String et = emails[i].substring(emails[i].lastIndexOf("@") + 1);
				// System.out.println(et);
				if (scores.containsKey(et)) {
					document.setBoost(scores.get(et));
				} else {
					document.setBoost(0.5f);
				}

				writer.addDocument(document);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
					writer = null;
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}

	}

	/*
	 * 建立IndexSearch的方法
	 */
	public IndexSearcher getSearch() {
		try {
			if (reader == null) {
				reader = IndexReader.open(directory);
			} else {
				IndexReader read = IndexReader.openIfChanged(reader);
				if (read != null) {
					reader.close();
					reader = read;
				}
			}
			return new IndexSearcher(reader);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 精確匹配查詢
	public void SearchByTerm(String field, String name, int num) {
		try {
			IndexSearcher search = getSearch();
			Query query = new TermQuery(new Term(field, name));
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 基於字串的範圍的查詢
	public void SearchByTermRange(String field, String start, String end,
			int num) {
		try {
			IndexSearcher search = getSearch();
			// 範圍查詢
			// true表示閉區間
			Query query = new TermRangeQuery(field, start, end, true, true);
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 基於數字的範圍的查詢
	public void SearchByNumricRange(String field, int start, int end, int num) {
		try {
			IndexSearcher search = getSearch();
			// 範圍查詢
			// true表示閉區間
			Query query = NumericRangeQuery.newIntRange(field, start, end,
					true, true);
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 字首搜尋
	public void SearchByPrefix(String field, String value, int num) {
		try {
			IndexSearcher search = getSearch();
			Query query = new PrefixQuery(new Term(field, value));
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 萬用字元搜尋
	public void SearchByWildCard(String field, String value, int num) {
		try {
			IndexSearcher search = getSearch();
			Query query = new WildcardQuery(new Term(field, value));
			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 多個條件搜尋
	public void SearchByBoolean(int num) {
		try {
			IndexSearcher search = getSearch();
			BooleanQuery query = new BooleanQuery();
			// Occur.Must表必須 Occur.SHOULD表示可有可無 Occur.MUST_NOT表示必須沒有
			query.add(new TermQuery(new Term("name", "lili")), Occur.MUST);
			query.add(new TermQuery(new Term("content", "hello")), Occur.MUST);

			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 短語查詢
	public void SearchByPhrase(int num) {
		try {
			IndexSearcher search = getSearch();
			PhraseQuery query = new PhraseQuery();
			// setSlop()設定跳數,及兩個單詞之間有幾個單詞
			query.setSlop(1);
			// 設定field欄位,即哪兩個單詞
			query.add(new Term("content", "i"));
			query.add(new Term("content", "basketball"));

			TopDocs tds = search.search(query, num);
			System.out.println("一共查詢了:" + tds.totalHits);
			for (ScoreDoc sdc : tds.scoreDocs) {
				Document doc = search.doc(sdc.doc);
				System.out.println(sdc.doc + doc.get("name") + "["
						+ doc.get("email") + "," + doc.get("id") + ","
						+ doc.get("attach") + "]");
			}
			search.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 模糊查詢
		public void SearchByFuzzy(int num) {
			try {
				IndexSearcher search = getSearch();
				Query query=new FuzzyQuery(new Term("name", "mirk"));
				
				TopDocs tds = search.search(query, num);
				System.out.println("一共查詢了:" + tds.totalHits);
				for (ScoreDoc sdc : tds.scoreDocs) {
					Document doc = search.doc(sdc.doc);
					System.out.println(sdc.doc + doc.get("name") + "["
							+ doc.get("email") + "," + doc.get("id") + ","
							+ doc.get("attach") + "]");
				}
				search.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	//基於字串操作
		public void SearchByQueryParse(Query query,int num){
			try {
				IndexSearcher search = getSearch();
				
				TopDocs tds = search.search(query, num);
				System.out.println("一共查詢了:" + tds.totalHits);
				for (ScoreDoc sdc : tds.scoreDocs) {
					Document doc = search.doc(sdc.doc);
					System.out.println(sdc.doc + doc.get("name") + "["
							+ doc.get("email") + "," + doc.get("id") + ","
							+ doc.get("attach") + "]");
				}
				search.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
}
package test.lucene.index;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;
import org.junit.Before;
import org.junit.Test;

public class SearchTest {
	private SearchUtil sutil;

	@Before
	public void init() throws Exception {
		sutil = new SearchUtil();
	}

	@Test
	public void searchByterm() {
		sutil.index();
		sutil.SearchByTerm("name", "mark", 3);
	}

	@Test
	public void searchByRangeTerm() {
		sutil.index();
		sutil.SearchByTermRange("id", "1", "3", 10);
		// 查詢name以a開頭和s結尾的
		sutil.SearchByTermRange("name", "a", "s", 10);
		// 由於attach是數字型別,使用termrange無法查詢
		sutil.SearchByTermRange("attach", "1", "5", 10);
	}

	@Test
	public void searchByNumricRange() {
		sutil.index();
		// 由於attach是數字型別,使用NumricRange進行查詢
		sutil.SearchByNumricRange("attach", 2, 5, 10);
	}

	@Test
	public void searchByPrefix() {
		sutil.index();
		// 字首搜尋
		sutil.SearchByPrefix("name", "l", 3);
	}

	@Test
	public void searchByWildCard() {
		sutil.index();
		// 萬用字元搜尋
		sutil.SearchByWildCard("name", "l*", 3);
	}

	@Test
	public void searchByBoolean() {
		sutil.index();
		// 多條件查詢
		sutil.SearchByBoolean(3);
	}

	@Test
	public void searchByPhrase() {
		sutil.index();
		// 短語查詢
		sutil.SearchByPhrase(5);
	}

	@Test
	public void searchByFuzzy() {
		sutil.index();
		// 模糊查詢
		sutil.SearchByFuzzy(5);
	}

	@Test
	public void searchByqueryParse() throws Exception {
		sutil.index();
		// 1.建立Parse物件(設定預設搜尋域為content)
		QueryParser parse = new QueryParser(Version.LUCENE_35, "content",
				new StandardAnalyzer(Version.LUCENE_35));
		// 改變空格的預設操作(改為AND型)
		parse.setDefaultOperator(Operator.AND);
		// 開啟第一個字元的萬用字元匹配(*xxx,?xxx),預設關閉,因為效率比較低
		parse.setAllowLeadingWildcard(true);
		// 2.通過parse生成query(搜尋content域中包含有like的)
		Query query = parse.parse("like");
		// 能夠一直加條件(空格預設就是OR)
		query = parse.parse("basketball i");
		// 改變搜尋域(域:值)
		query = parse.parse("name:mark");
		// 同樣能進行*或?的萬用字元匹配(萬用字元預設不能放在首位)
		query = parse.parse("name:*i");
		// name中不包含mark,但是content中包含basketball(-和+必須放在域說明的前面)
		query = parse.parse("- name:mark + basketball");
		// id的1~3(TO表示一個閉區間,TO必須是大寫的)
		query = parse.parse("id:[1 TO 3]");
		// {}表示1~3的開區間匹配
		query = parse.parse("id:{1 TO 3}");
		// name域值是lili或mark,預設域值是game
		query = parse.parse("name:(lili OR mark) AND game");
		// 兩個‘’號表示短語匹配
		query = parse.parse("'i like basketball'");
		// 表示i basketball之間有一個單詞遺漏的匹配
		query = parse.parse("\"i basketball\"~1");
		// 加個~就能模糊查詢mark
		query = parse.parse("name:mirk~");
		// 沒有辦法匹配數字範圍(自己擴充套件parse)
		query = parse.parse("attach:[1 TO 3]");
		sutil.SearchByQueryParse(query, 5);
	}
}



相關推薦

Lucene查詢方式總結

--------------------------------------------------IndexReader的設計--------------------------------------------------IndexReader的建立需要消耗大量記憶體

SQLAlchemy 幾種查詢方式總結

記錄總數查詢: from sqlalchemy import func # count User records, without # using a subquery. session.query(func.count(User.id)) # return count of user "id" group

Spring data jpa 複雜動態查詢方式總結

一.Spring data jpa 簡介 首先我並不推薦使用jpa作為ORM框架,畢竟對於負責查詢的時候還是不太靈活,還是建議使用mybatis,自己寫sql比較好.但是如果公司用這個就沒辦法了,可以學習一下,對於簡單查詢還是非常好用的.     首先JPA是Java

lucene多種查詢方式

package junit; import java.io.File; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.List; imp

MySQL索引及查詢優化總結

存儲 一行 -1 type 一定的 關鍵技術 表示 智能 string類型 一個簡單的對比測試 前面的案例中,c2c_zwdb.t_file_count表只有一個自增id,FFileName字段未加索引的sql執行情況如下: 在上圖中,type=all,key=nul

[OS] Linux進程、線程通信方式總結

信號量 all http 命名 信號 .com 數據結構 rem pip 轉自:http://blog.sina.com.cn/s/blog_64b9c6850100ub80.html Linux系統中的進程通信方式主要以下幾種: 同一主機上的進程通信方式 * UNI

C#打開SDE數據庫的幾種方式總結

tex 用戶 ops 總結 param word editor conn tor 轉自謝燦軟件原文 C#打開SDE數據庫的幾種方式總結 1.通過指定連接屬性參數打開數據庫 /// <param name="server">數據庫服務器名&

CSS居中方式總結

str code pad enter align play otto 總結 相等 1.text-align:center;   使用以上方式居中是將父級容器中display:inline;的行內元素或者文字進行水平居中。 2.inline-height:(height)值;

樣式導入方式總結

shee sea icon 問題 itl ica span 比較 content link與import <link href="index.css" rel="stylesheet"> <style type="text/css"> @im

Elasticsearch學習之多種查詢方式

完全 mar commerce 生產 pro 命令行 str 令行 {} 1. query string search   搜索全部商品:GET /ecommerce/product/_search   took:耗費了幾毫秒  timed_out:是否超時,這裏是沒有  

Hbase 統計表行數的3種方式總結

bsp ping love and interval board jar ive add 有些時候需要我們去統計某一個Hbase表的行數,由於hbase本身不支持SQL語言,只能通過其他方式實現。可以通過一下幾種方式實現hbase表的行數統計工作:1.count命令最直接的

9.9-全棧Java筆記:遍歷集合的N種方式總結&Collections工具類

java遍歷集合的N種方式總結【示例1】遍歷List方法1,使用普通for循環for(int i=0;i<list.size();i++){ //list為集合的對象名 String temp = (String)list.get(i); System.out.println

文本與集合的讀取寫入方式總結

void space -1 方式 static div throws col arraylist //1.從文本中讀取並添加到集合,按行讀取 1 public static void main(String[] args) throws IOException { 2

JS對象繼承的幾種方式總結

tor style div on() 引用 super 繼承 不兼容 font 今天學習了一下js的繼承,js中的繼承主要分四種,原型繼承,構造函數繼承,call/apply繼承以及es6的extend繼承。1.原型繼承:原型繼承主要利用js對象的prototype引用父類

JavaScript創建對象的幾種方式總結

引用 常用 添加 耦合 取代 共享 fun 支持 高程   ECMA把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或者函數。 1. 使用Object構造函數創建對象   創建自定義對象的最簡單的方式就是創建一個Object的實例,然後再為它添加屬性和方法。

JavaScript實現繼承的幾種方式總結

相同 實踐 extend sta 執行 instance () class new 雖然在ES6中有了繼承,使用extends關鍵字就能實現。本篇講的不是這種,而是ES6之前的幾種實現繼承的方式。 (一)原型鏈 ECMAScript中將原型鏈作為實現繼承的主要方法。其基本思

浮點數float累加誤差解決方式總結

turn ble should 也有 方法 git 如果 precision https 首先是float累加產生誤差的原因,該部分轉自:http://blog.csdn.net/zhrh0096/article/details/38589067 1. 浮點數IEEE 7

Hibernate學習10——Hibernate 查詢方式

9.png property ice pub gets reat sed desc ring 本章主要是以查詢Student的例子: Student.java: package com.cy.model; public class Student { priv

Asp.Net中的三種分頁方式總結

rom chang clas 綁定 select proc dll xtend tinc 本人ASP.net初學,網上找了一些分頁的資料,看到這篇文章,沒看到作者在名字,我轉了你的文章,只為我可以用的時候方便查看,2010的文章了,不知道這技術是否過期。 以下才是正文

Linux進程間通信的幾種方式總結--linux內核剖析(七)

字節流 標準 包含 down pro trac posix共享內存 ++ 實現 進程間通信概述 進程通信的目的 傳輸數據 一個進程須要將它的數據發送給還有一個進程。發送的數據量在一個字節到幾M字節之間 共享數據 多個進程想要操作共享