一、什麼是條件搜索java
用關健字與指定的單列或多例進行匹配的搜索apache
二、單字段條件搜索ide
QueryParser queryParser = new QueryParser(LuceneUtils.getVersion(),"content",LuceneUtils.getAnalyzer());
三、多字段條件搜索,項目中提倡多字段搜索spa
QueryParser queryParser = new MultiFieldQueryParser(LuceneUtils.getVersion(),new String[]{"content","title"},LuceneUtils.getAnalyzer());
TestSearch.java對象
package com.rk.lucene.g_search; import java.util.ArrayList; import java.util.List; import org.apache.lucene.document.Document; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.junit.Test; import com.rk.lucene.entity.Article; import com.rk.lucene.utils.LuceneUtils; public class TestSearch { @Test public void testAdd() throws Exception{ List<Article> list = new ArrayList<Article>(); list.add(new Article(1, "疾風之刃", "《疾風之刃》是一款超動做3D動漫風網遊。做爲新一代動做遊戲,《疾風之刃》呈現出極致華麗的動做表演,精心打磨出的打擊感震撼人心。")); list.add(new Article(2, "月光疾風", "月光疾風,日本動漫《火影忍者》中的人物,比較我的主義,性格溫和。火之國木葉村的特別上忍,中忍考試正賽預選的考官,體質彷佛很很差,有着嚴重的黑眼圈、臉色蒼白且常常咳嗽,善用劍術。")); list.add(new Article(3, "疾風航班中文版下載", "《疾風航班》是一款優質的動做模擬遊戲。遊戲中包括亞歐美洲,乃至飛往太空的5條航線,共計50個按部就班的關卡,以及具備挑戰性的Expert級別評定,每一個關卡結束後還可進入商店對主角和飛機進...")); list.add(new Article(4, "八神疾風", "八神疾風(CV:植田佳奈)是日本動漫《魔法少女奈葉A's》首次登場的女角色。暗之書事件中心人物,時空管理局魔導師,擅長貝爾卡式廣域·遠程魔法。")); list.add(new Article(5, "逝去的疾風", "大戰中飛得最快的日本飛機,恐怕要數「疾風」戰鬥機了,它由中島飛機廠研製生產,制式型號爲: 四式單(座)戰(鬥機),代號キ-84(讀做 Ki-84)。")); list.add(new Article(6, "疾風劍豪 亞索", "亞索是一個百折不屈的男人,仍是一名身手敏捷的劍客,可以運用風的力量來斬殺敵人。這位曾經春風得意的戰士由於誣陷而身敗名裂,而且被迫捲入了一場使人絕望的生存之...")); list.add(new Article(7, "疾風知勁草", "疾風知勁草,謂在猛烈的大風中,可看出什麼樣的草是強勁的。比喻意志堅決,經得起考驗。出自《東觀漢記·王霸傳》:「上謂霸曰:‘潁川從我者皆逝,而子獨留,始驗疾風知勁草。...")); LuceneUtils.addAll(list); } @Test public void testSearch() throws Exception{ List<Article> list = new ArrayList<Article>(); String keyword = "疾風"; //單字段搜索 //QueryParser queryParser = new QueryParser(LuceneUtils.getVersion(),"content", LuceneUtils.getAnalyzer()); //多字段搜索,好處:搜索的範圍大,最大限度匹配搜索結果 QueryParser queryParser = new MultiFieldQueryParser( LuceneUtils.getVersion(), new String[]{"content","title"}, LuceneUtils.getAnalyzer()); Query query = queryParser.parse(keyword); IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory()); TopDocs topDocs = indexSearcher.search(query, 10000); for(int i=0;i<topDocs.scoreDocs.length;i++){ ScoreDoc scoreDoc = topDocs.scoreDocs[i]; int docIndex = scoreDoc.doc; Document document = indexSearcher.doc(docIndex); System.out.println("編號爲"+document.get("id")+"號的文章得分是" + scoreDoc.score); Article article = LuceneUtils.document2javabean(document, Article.class); list.add(article); } indexSearcher.close(); for(Article article : list){ System.out.println(article); } } }
單列搜索結果索引
編號爲1號的文章得分是0.32994816 編號爲7號的文章得分是0.28870463 編號爲4號的文章得分是0.23330858 編號爲5號的文章得分是0.23330858 編號爲2號的文章得分是0.20414501 編號爲3號的文章得分是0.20414501
多列搜索結果遊戲
編號爲1號的文章得分是0.8313483 編號爲4號的文章得分是0.76052743 編號爲2號的文章得分是0.73915535 編號爲7號的文章得分是0.72742975 編號爲5號的文章得分是0.68683356 編號爲3號的文章得分是0.5180738 編號爲6號的文章得分是0.44216305
LuceneUtils.java事件
package com.rk.lucene.utils; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexWriter.MaxFieldLength; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import com.rk.lucene.entity.Page; public class LuceneUtils { private static Directory directory; private static Version version; private static Analyzer analyzer; private static MaxFieldLength maxFieldLength; private static final String LUCENE_DIRECTORY= "D:/rk/indexDB"; static{ try { directory = FSDirectory.open(new File(LUCENE_DIRECTORY)); version = Version.LUCENE_30; analyzer = new StandardAnalyzer(version); maxFieldLength = MaxFieldLength.LIMITED; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } //不讓外部new當前幫助類的對象 private LuceneUtils(){} public static <T> void pagination(Page<T> page,String field,String keyword,Class<T> clazz) throws Exception{ QueryParser queryParser = new QueryParser(getVersion(), field, getAnalyzer()); Query query = queryParser.parse(keyword); IndexSearcher indexSearcher = new IndexSearcher(getDirectory()); TopDocs topDocs = indexSearcher.search(query, 200); int totalHits = topDocs.totalHits; int curPage = page.getCurPage(); int pageSize = page.getPageSize(); int quotient = totalHits / pageSize; int remainder = totalHits % pageSize; int totalPages = remainder==0 ? quotient : quotient+1; int startIndex = (curPage-1) * pageSize; int stopIndex = Math.min(startIndex + pageSize, totalHits); List<T> list = page.getItems(); if(list == null){ list = new ArrayList<T>(); page.setItems(list); } list.clear(); for(int i=startIndex;i<stopIndex;i++){ ScoreDoc scoreDoc = topDocs.scoreDocs[i]; int docIndex = scoreDoc.doc; Document document = indexSearcher.doc(docIndex); T t = document2javabean(document, clazz); list.add(t); } page.setTotalPages(totalPages); page.setTotalItems(totalHits); indexSearcher.close(); } public static <T> void add(T t) throws Exception{ Document document = javabean2document(t); IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength()); indexWriter.addDocument(document); indexWriter.close(); } public static <T> void addAll(List<T> list) throws Exception{ IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength()); for(T t : list){ Document doc = javabean2document(t); indexWriter.addDocument(doc); } indexWriter.close(); } public static <T> void update(String field,String value,T t) throws Exception{ Document document = javabean2document(t); IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength()); indexWriter.updateDocument(new Term(field,value), document); indexWriter.close(); } public static <T> void delete(String field,String value) throws Exception{ IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength()); indexWriter.deleteDocuments(new Term(field,value)); indexWriter.close(); } /** * 刪除全部記錄 */ public static void deleteAll() throws Exception { IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength()); indexWriter.deleteAll(); indexWriter.close(); } /** * 根據關鍵字進行搜索 */ public static <T> List<T> search(String field,String keyword,int topN,Class<T> clazz) throws Exception{ List<T> list = new ArrayList<T>(); QueryParser queryParser = new QueryParser(getVersion(), field, getAnalyzer()); Query query = queryParser.parse(keyword); IndexSearcher indexSearcher = new IndexSearcher(getDirectory()); TopDocs topDocs = indexSearcher.search(query, topN); for(int i=0;i<topDocs.scoreDocs.length;i++){ ScoreDoc scoreDoc = topDocs.scoreDocs[i]; int docIndex = scoreDoc.doc; System.out.println("文檔索引號" + docIndex + ",文檔得分:" + scoreDoc.score); Document document = indexSearcher.doc(docIndex); T entity = (T) document2javabean(document, clazz); list.add(entity); } indexSearcher.close(); return list; } /** * 打印List */ public static <T> void printList(List<T> list){ if(list != null && list.size()>0){ for(T t : list){ System.out.println(t); } } } //將JavaBean轉成Document對象 public static Document javabean2document(Object obj) throws Exception{ //建立Document對象 Document document = new Document(); //獲取obj引用的對象字節碼 Class clazz = obj.getClass(); //經過對象字節碼獲取私有的屬性 java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields(); //迭代 for(java.lang.reflect.Field reflectField : reflectFields){ //反射 reflectField.setAccessible(true); //獲取字段名 String name = reflectField.getName(); //獲取字段值 String value = reflectField.get(obj).toString(); //加入到Document對象中去,這時javabean的屬性與document對象的屬性相同 document.add(new Field(name, value, Store.YES, Index.ANALYZED)); } //返回document對象 return document; } //將Document對象轉換成JavaBean對象 public static <T> T document2javabean(Document document,Class<T> clazz) throws Exception{ T obj = clazz.newInstance(); java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields(); for(java.lang.reflect.Field reflectField : reflectFields){ reflectField.setAccessible(true); String name = reflectField.getName(); String value = document.get(name); BeanUtils.setProperty(obj, name, value); } return obj; } public static Directory getDirectory() { return directory; } public static void setDirectory(Directory directory) { LuceneUtils.directory = directory; } public static Version getVersion() { return version; } public static void setVersion(Version version) { LuceneUtils.version = version; } public static Analyzer getAnalyzer() { return analyzer; } public static void setAnalyzer(Analyzer analyzer) { LuceneUtils.analyzer = analyzer; } public static MaxFieldLength getMaxFieldLength() { return maxFieldLength; } public static void setMaxFieldLength(MaxFieldLength maxFieldLength) { LuceneUtils.maxFieldLength = maxFieldLength; } }