`
zcwfeng
  • 浏览: 106565 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
社区版块
存档分类
最新评论

lucene第二步,lucene搜索

 
阅读更多

出自:http://blog.csdn.net/wxwzy738/article/details/8799656 的整理

1、工程结构


2、查询语法代码

  1. packageorg.itat.index;
  2. importjava.io.File;
  3. importjava.io.IOException;
  4. importjava.io.StringReader;
  5. importjava.text.ParseException;
  6. importjava.text.SimpleDateFormat;
  7. importjava.util.Date;
  8. importjava.util.HashMap;
  9. importjava.util.Map;
  10. importorg.apache.lucene.analysis.Analyzer;
  11. importorg.apache.lucene.analysis.TokenStream;
  12. importorg.apache.lucene.analysis.standard.StandardAnalyzer;
  13. importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;
  14. importorg.apache.lucene.document.Document;
  15. importorg.apache.lucene.document.Field;
  16. importorg.apache.lucene.document.NumericField;
  17. importorg.apache.lucene.index.CorruptIndexException;
  18. importorg.apache.lucene.index.IndexReader;
  19. importorg.apache.lucene.index.IndexWriter;
  20. importorg.apache.lucene.index.IndexWriterConfig;
  21. importorg.apache.lucene.index.Term;
  22. importorg.apache.lucene.queryParser.QueryParser;
  23. importorg.apache.lucene.search.BooleanClause.Occur;
  24. importorg.apache.lucene.search.BooleanQuery;
  25. importorg.apache.lucene.search.FuzzyQuery;
  26. importorg.apache.lucene.search.IndexSearcher;
  27. importorg.apache.lucene.search.NumericRangeQuery;
  28. importorg.apache.lucene.search.PhraseQuery;
  29. importorg.apache.lucene.search.PrefixQuery;
  30. importorg.apache.lucene.search.Query;
  31. importorg.apache.lucene.search.ScoreDoc;
  32. importorg.apache.lucene.search.TermQuery;
  33. importorg.apache.lucene.search.TermRangeQuery;
  34. importorg.apache.lucene.search.TopDocs;
  35. importorg.apache.lucene.search.WildcardQuery;
  36. importorg.apache.lucene.store.Directory;
  37. importorg.apache.lucene.store.FSDirectory;
  38. importorg.apache.lucene.store.LockObtainFailedException;
  39. importorg.apache.lucene.util.Version;
  40. importorg.wltea.analyzer.lucene.IKAnalyzer;
  41. publicclassSearcherUtil{
  42. privateDirectorydirectory;
  43. privateAnalyzeranalyzer=newIKAnalyzer();
  44. privateIndexReaderreader;
  45. privateString[]ids={"1","2","3","4","5","6"};
  46. privateString[]emails={"aa@itat.org","bb@itat.org","cc@cc.org","dd@sina.org","ee@zttc.edu","ff@itat.org"};
  47. privateString[]contents={
  48. "welcometovisitedthespace,Ilikebook",
  49. "helloboy,Ilikepingpengball",
  50. "mynameisccIlikegame",
  51. "Ilikefootball",
  52. "IlikefootballandIlikebasketballtoo",
  53. "Ilikemovieandswim"
  54. };
  55. privateDate[]dates=null;
  56. privateint[]attachs={2,3,1,4,5,5};
  57. privateString[]names={"zhangsan","lisi","john","jetty","mike","jake"};
  58. privateMap<String,Float>scores=newHashMap<String,Float>();
  59. publicSearcherUtil(){
  60. //directory=newRAMDirectory();
  61. try{
  62. directory=FSDirectory.open(newFile("F:\\Workspaces\\lucenes\\02_lucene_searcher\\index"));
  63. setDates();
  64. scores.put("itat.org",2.0f);
  65. scores.put("zttc.edu",1.5f);
  66. //index();
  67. }catch(IOExceptione){
  68. e.printStackTrace();
  69. }
  70. }
  71. privatevoidsetDates(){
  72. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  73. try{
  74. dates=newDate[ids.length];
  75. dates[0]=sdf.parse("2010-02-19");
  76. dates[1]=sdf.parse("2012-01-11");
  77. dates[2]=sdf.parse("2011-09-19");
  78. dates[3]=sdf.parse("2010-12-22");
  79. dates[4]=sdf.parse("2012-01-01");
  80. dates[5]=sdf.parse("2011-05-19");
  81. }catch(ParseExceptione){
  82. e.printStackTrace();
  83. }
  84. }
  85. publicvoidindex(){
  86. IndexWriterwriter=null;
  87. try{
  88. writer=newIndexWriter(directory,newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  89. writer.deleteAll();
  90. Documentdoc=null;
  91. for(inti=0;i<ids.length;i++){
  92. doc=newDocument();
  93. doc.add(newField("id",ids[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  94. doc.add(newField("email",emails[i],Field.Store.YES,Field.Index.NOT_ANALYZED));
  95. doc.add(newField("content",contents[i],Field.Store.NO,Field.Index.ANALYZED));
  96. doc.add(newField("name",names[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  97. //存储数字
  98. doc.add(newNumericField("attach",Field.Store.YES,true).setIntValue(attachs[i]));
  99. //存储日期
  100. doc.add(newNumericField("date",Field.Store.YES,true).setLongValue(dates[i].getTime()));
  101. Stringet=emails[i].substring(emails[i].lastIndexOf("@")+1);
  102. if(scores.containsKey(et)){
  103. doc.setBoost(scores.get(et));
  104. }else{
  105. doc.setBoost(0.5f);
  106. }
  107. writer.addDocument(doc);
  108. }
  109. }catch(CorruptIndexExceptione){
  110. e.printStackTrace();
  111. }catch(LockObtainFailedExceptione){
  112. e.printStackTrace();
  113. }catch(IOExceptione){
  114. e.printStackTrace();
  115. }finally{
  116. try{
  117. if(writer!=null)writer.close();
  118. }catch(CorruptIndexExceptione){
  119. e.printStackTrace();
  120. }catch(IOExceptione){
  121. e.printStackTrace();
  122. }
  123. }
  124. }
  125. publicIndexSearchergetSearcher(){
  126. try{
  127. if(reader==null){
  128. reader=IndexReader.open(directory);
  129. }else{
  130. IndexReadertr=IndexReader.openIfChanged(reader);
  131. if(tr!=null){
  132. reader.close();
  133. reader=tr;
  134. }
  135. }
  136. returnnewIndexSearcher(reader);
  137. }catch(CorruptIndexExceptione){
  138. e.printStackTrace();
  139. }catch(IOExceptione){
  140. e.printStackTrace();
  141. }
  142. returnnull;
  143. }
  144. publicIndexSearchergetSearcher(Directorydirectory){
  145. try{
  146. if(reader==null){
  147. reader=IndexReader.open(directory);
  148. }else{
  149. IndexReadertr=IndexReader.openIfChanged(reader);
  150. if(tr!=null){
  151. reader.close();
  152. reader=tr;
  153. }
  154. }
  155. returnnewIndexSearcher(reader);
  156. }catch(CorruptIndexExceptione){
  157. e.printStackTrace();
  158. }catch(IOExceptione){
  159. e.printStackTrace();
  160. }
  161. returnnull;
  162. }
  163. publicvoidsearchByTerm(Stringfield,Stringname,intnum){
  164. try{
  165. IndexSearchersearcher=getSearcher();
  166. Queryquery=newTermQuery(newTerm(field,name));
  167. TopDocstds=searcher.search(query,num);
  168. printDocument(searcher,tds);
  169. searcher.close();
  170. }catch(CorruptIndexExceptione){
  171. e.printStackTrace();
  172. }catch(IOExceptione){
  173. e.printStackTrace();
  174. }
  175. }
  176. publicvoidsearchByTermToken(Stringfield,Stringname,intnum){
  177. try{
  178. IndexSearchersearcher=getSearcher();
  179. //Queryquery=newTermQuery(newTerm(field,name));
  180. //当用户输入两个关键字时,QueryParser默认它们之间的关系为“或”关系
  181. //下面这么写的话在对用户输入进行扫描时,就会用空格分开的关键字理解为“与”,
  182. //其实也就是构建了一个“与”关系的布尔型查询
  183. //parser.setDefaultOperator(Operator.AND);
  184. QueryParserparser=newQueryParser(Version.LUCENE_35,field,analyzer);
  185. Stringk=analyzerKey(name);
  186. Queryquery=parser.parse(name);
  187. TopDocstds=searcher.search(query,num);
  188. printDocument(searcher,tds);
  189. searcher.close();
  190. }catch(CorruptIndexExceptione){
  191. e.printStackTrace();
  192. }catch(Exceptione){
  193. e.printStackTrace();
  194. }
  195. }
  196. privateStringanalyzerKey(Stringkey){
  197. //StandardAnalyzeranalyzer=newStandardAnalyzer(Version.LUCENE_35);
  198. StringReaderreader=newStringReader(key);
  199. TokenStreamtokenStream=analyzer.tokenStream("",reader);
  200. CharTermAttributetermattr=tokenStream.addAttribute(CharTermAttribute.class);
  201. StringBuildersb=newStringBuilder();
  202. try{
  203. while(tokenStream.incrementToken()){
  204. Stringk=termattr.toString();
  205. sb.append(k).append("");
  206. }
  207. }catch(IOExceptione){
  208. e.printStackTrace();
  209. }
  210. key=sb.toString().trim();
  211. key=key.replaceAll("\\s+","AND");
  212. returnsb.toString();
  213. }
  214. publicvoidprintDocument(IndexSearchersearcher,TopDocstds){
  215. System.out.println("共查询了【"+tds.totalHits+"】条");
  216. for(ScoreDocsd:tds.scoreDocs){
  217. try{
  218. Documentdoc=searcher.doc(sd.doc);
  219. System.out.println("filename:"+doc.get("filename"));
  220. System.out.println("path:"+doc.get("path"));
  221. System.out.println("date:"+doc.get("date"));
  222. System.out.println("size:"+doc.get("size"));
  223. System.out.println("content:"+doc.get("content"));
  224. System.out.println("-------------------------------------------");
  225. }catch(CorruptIndexExceptione){
  226. e.printStackTrace();
  227. }catch(IOExceptione){
  228. e.printStackTrace();
  229. }
  230. }
  231. }
  232. publicvoidsearchByTermRange(Stringfield,Stringstart,Stringend,intnum){
  233. try{
  234. IndexSearchersearcher=getSearcher();
  235. Queryquery=newTermRangeQuery(field,start,end,true,true);
  236. TopDocstds=searcher.search(query,num);
  237. printDocument(searcher,tds);
  238. searcher.close();
  239. }catch(CorruptIndexExceptione){
  240. e.printStackTrace();
  241. }catch(IOExceptione){
  242. e.printStackTrace();
  243. }
  244. }
  245. /**
  246. *建立索引时:使用的Field,而使用NumericRangeQuery,必须使用NumericField
  247. *@paramfield
  248. *@paramstart
  249. *@paramend
  250. *@paramnum
  251. */
  252. publicvoidsearchByNumricRange(Stringfield,intstart,intend,intnum){
  253. try{
  254. IndexSearchersearcher=getSearcher();
  255. Queryquery=NumericRangeQuery.newIntRange(field,start,end,true,true);
  256. //DateTools.dateToString(newDate(),null);
  257. TopDocstds=searcher.search(query,num);
  258. printDocument(searcher,tds);
  259. searcher.close();
  260. }catch(CorruptIndexExceptione){
  261. e.printStackTrace();
  262. }catch(IOExceptione){
  263. e.printStackTrace();
  264. }
  265. }
  266. publicvoidsearchByPrefix(Stringfield,Stringvalue,intnum){
  267. try{
  268. IndexSearchersearcher=getSearcher();
  269. Queryquery=newPrefixQuery(newTerm(field,value));
  270. TopDocstds=searcher.search(query,num);
  271. printDocument(searcher,tds);
  272. searcher.close();
  273. }catch(CorruptIndexExceptione){
  274. e.printStackTrace();
  275. }catch(IOExceptione){
  276. e.printStackTrace();
  277. }
  278. }
  279. publicvoidsearchByWildcard(Stringfield,Stringvalue,intnum){
  280. try{
  281. IndexSearchersearcher=getSearcher();
  282. //在传入的value中可以使用通配符:?和*,?表示匹配一个字符,*表示匹配任意多个字符
  283. Queryquery=newWildcardQuery(newTerm(field,value));
  284. TopDocstds=searcher.search(query,num);
  285. printDocument(searcher,tds);
  286. searcher.close();
  287. }catch(CorruptIndexExceptione){
  288. e.printStackTrace();
  289. }catch(IOExceptione){
  290. e.printStackTrace();
  291. }
  292. }
  293. publicvoidsearchByBoolean(intnum){
  294. try{
  295. IndexSearchersearcher=getSearcher();
  296. BooleanQueryquery=newBooleanQuery();
  297. /*
  298. *BooleanQuery可以连接多个子查询
  299. *Occur.MUST表示必须出现
  300. *Occur.SHOULD表示可以出现
  301. *Occur.MUSE_NOT表示不能出现
  302. */
  303. query.add(newTermQuery(newTerm("name","3")),Occur.MUST_NOT);
  304. query.add(newTermQuery(newTerm("content","健壮")),Occur.SHOULD);
  305. TopDocstds=searcher.search(query,num);
  306. printDocument(searcher,tds);
  307. searcher.close();
  308. }catch(CorruptIndexExceptione){
  309. e.printStackTrace();
  310. }catch(IOExceptione){
  311. e.printStackTrace();
  312. }
  313. }
  314. publicvoidsearchByPhrase(intnum){
  315. try{
  316. IndexSearchersearcher=getSearcher();
  317. PhraseQueryquery=newPhraseQuery();
  318. query.setSlop(10);
  319. query.add(newTerm("content","java"));
  320. //第一个Term
  321. query.add(newTerm("content","程序"));
  322. //产生距离之后的第二个Term
  323. //query.add(newTerm("content","football"));
  324. TopDocstds=searcher.search(query,num);
  325. printDocument(searcher,tds);
  326. searcher.close();
  327. }catch(CorruptIndexExceptione){
  328. e.printStackTrace();
  329. }catch(IOExceptione){
  330. e.printStackTrace();
  331. }
  332. }
  333. /**
  334. *查询用于匹配与指定项相似的项
  335. *默认是匹配一个有不同的,其他一样的,比如like和mike,就是距离算法的相似距离为1
  336. *这种方式少用,影响效率
  337. */
  338. publicvoidsearchByFuzzy(intnum){
  339. try{
  340. IndexSearchersearcher=getSearcher();
  341. //最后两个参数为匹配率和距离
  342. FuzzyQueryquery=newFuzzyQuery(newTerm("content","总统"),0.4f,0);
  343. System.out.println(query.getPrefixLength());
  344. System.out.println(query.getMinSimilarity());
  345. TopDocstds=searcher.search(query,num);
  346. printDocument(searcher,tds);
  347. searcher.close();
  348. }catch(CorruptIndexExceptione){
  349. e.printStackTrace();
  350. }catch(IOExceptione){
  351. e.printStackTrace();
  352. }
  353. }
  354. publicvoidsearchByQueryParse(Queryquery,intnum){
  355. try{
  356. IndexSearchersearcher=getSearcher();
  357. TopDocstds=searcher.search(query,num);
  358. System.out.println("一共查询了:"+tds.totalHits);
  359. for(ScoreDocsd:tds.scoreDocs){
  360. Documentdoc=searcher.doc(sd.doc);
  361. System.out.println(doc.get("id")+"---->"+
  362. doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
  363. doc.get("attach")+","+doc.get("date")+"=="+sd.score);
  364. }
  365. searcher.close();
  366. }catch(CorruptIndexExceptione){
  367. e.printStackTrace();
  368. }catch(IOExceptione){
  369. e.printStackTrace();
  370. }
  371. }
  372. /**
  373. *lucene3.5之前采用的是一种再查询的方式,也就是说先把全部的结果的docid查询出来,然后
  374. *分页得到该页的docid,然后根据docid得到document信息,
  375. *lucene官方是说他的速度已经够快,再查询不会有效率问题
  376. *@paramquery
  377. *@parampageIndex
  378. *@parampageSize
  379. */
  380. publicvoidsearchPage(Stringquery,intpageIndex,intpageSize){
  381. try{
  382. Directorydir=FileIndexUtils.getDirectory();
  383. IndexSearchersearcher=getSearcher(dir);
  384. QueryParserparser=newQueryParser(Version.LUCENE_35,"content",analyzer);
  385. Queryq=parser.parse(query);
  386. TopDocstds=searcher.search(q,500);
  387. ScoreDoc[]sds=tds.scoreDocs;
  388. intstart=(pageIndex-1)*pageSize;
  389. intend=pageIndex*pageSize;
  390. for(inti=start;i<end;i++){
  391. Documentdoc=searcher.doc(sds[i].doc);
  392. System.out.println("filename:"+doc.get("filename"));
  393. System.out.println("path:"+doc.get("path"));
  394. System.out.println("date:"+doc.get("date"));
  395. System.out.println("size:"+doc.get("size"));
  396. System.out.println("content:"+doc.get("content"));
  397. System.out.println("-------------------------------------------");
  398. }
  399. searcher.close();
  400. }catch(org.apache.lucene.queryParser.ParseExceptione){
  401. e.printStackTrace();
  402. }catch(IOExceptione){
  403. e.printStackTrace();
  404. }
  405. }
  406. /**
  407. *目前没有办法只取当前这页的数据,而是要全部查询然后得到docid
  408. *一种增加效率的方式是取的条数做下限制,比如不要每次都取500条,
  409. *也是把取的条数设置为当前页的所在位置数,比如每页10条,
  410. *取第一页数据则取10条,取第二页则取20条,取五页则去50条
  411. *根据页码和分页大小获取上一次的最后一个ScoreDoc
  412. */
  413. privateScoreDocgetLastScoreDoc(intpageIndex,intpageSize,Queryquery,IndexSearchersearcher)throwsIOException{
  414. if(pageIndex==1)returnnull;//如果是第一页就返回空
  415. intnum=pageSize*(pageIndex-1);//获取上一页的数量
  416. TopDocstds=searcher.search(query,num);
  417. returntds.scoreDocs[num-1];
  418. }
  419. /**
  420. *使用这种方式的话是把上一页的最后一个元素给拿到,然后再把pagesize传入,
  421. *就可以得到当页的数据,其实就是简便了查询,原理还是把全部的docid查询后在得到document
  422. *@paramquery
  423. *@parampageIndex
  424. *@parampageSize
  425. */
  426. publicvoidsearchPageByAfter(Stringquery,intpageIndex,intpageSize){
  427. try{
  428. Directorydir=FileIndexUtils.getDirectory();
  429. IndexSearchersearcher=getSearcher(dir);
  430. QueryParserparser=newQueryParser(Version.LUCENE_35,"content",analyzer);
  431. Queryq=parser.parse(query);
  432. //先获取上一页的最后一个元素
  433. ScoreDoclastSd=getLastScoreDoc(pageIndex,pageSize,q,searcher);
  434. //通过最后一个元素搜索下页的pageSize个元素
  435. TopDocstds=searcher.searchAfter(lastSd,q,pageSize);
  436. printDocument(searcher,tds);
  437. searcher.close();
  438. }catch(org.apache.lucene.queryParser.ParseExceptione){
  439. e.printStackTrace();
  440. }catch(IOExceptione){
  441. e.printStackTrace();
  442. }
  443. }
  444. publicvoidsearchNoPage(Stringquery){
  445. try{
  446. Directorydir=FileIndexUtils.getDirectory();
  447. IndexSearchersearcher=getSearcher(dir);
  448. QueryParserparser=newQueryParser(Version.LUCENE_35,"content",newStandardAnalyzer(Version.LUCENE_35));
  449. Queryq=parser.parse(query);
  450. TopDocstds=searcher.search(q,20);
  451. ScoreDoc[]sds=tds.scoreDocs;
  452. for(inti=0;i<sds.length;i++){
  453. Documentdoc=searcher.doc(sds[i].doc);
  454. System.out.println(sds[i].doc+":"+doc.get("path")+"-->"+doc.get("filename"));
  455. }
  456. searcher.close();
  457. }catch(org.apache.lucene.queryParser.ParseExceptione){
  458. e.printStackTrace();
  459. }catch(IOExceptione){
  460. e.printStackTrace();
  461. }
  462. }
  463. }

3、查询语法的测试单元类

  1. packageorg.itat.test;
  2. importjava.io.File;
  3. importjava.io.IOException;
  4. importorg.apache.commons.io.FileUtils;
  5. importorg.apache.commons.io.FilenameUtils;
  6. importorg.apache.lucene.analysis.Analyzer;
  7. importorg.apache.lucene.analysis.standard.StandardAnalyzer;
  8. importorg.apache.lucene.queryParser.ParseException;
  9. importorg.apache.lucene.queryParser.QueryParser;
  10. importorg.apache.lucene.search.Query;
  11. importorg.apache.lucene.util.Version;
  12. importorg.itat.index.FileIndexUtils;
  13. importorg.itat.index.SearcherUtil;
  14. importorg.junit.Before;
  15. importorg.junit.Test;
  16. importorg.wltea.analyzer.lucene.IKAnalyzer;
  17. publicclassTestSearch{
  18. privateSearcherUtilsu;
  19. privateAnalyzeranalyzer=newIKAnalyzer();
  20. @Before
  21. publicvoidinit(){
  22. su=newSearcherUtil();
  23. }
  24. @Test
  25. publicvoidtestCopyFiles(){
  26. try{
  27. Filefile=newFile("F:\\Workspaces\\lucenes\\02_lucene_searcher\\resource");
  28. for(Filef:file.listFiles()){
  29. StringdestFileName=FilenameUtils.getFullPath(f.getAbsolutePath())+
  30. FilenameUtils.getBaseName(f.getName())+".she";
  31. FileUtils.copyFile(f,newFile(destFileName));
  32. }
  33. }catch(IOExceptione){
  34. e.printStackTrace();
  35. }
  36. }
  37. @Test
  38. publicvoidsearchByTerm(){
  39. //su.searchByTerm("content","",10);
  40. su.searchByTermToken("content","头脑风暴",10);
  41. }
  42. @Test
  43. publicvoidsearchByTermRange(){
  44. //查询name以a开头和s结尾的
  45. //su.searchByTermRange("name","a","s",10);
  46. //由于attachs是数字类型,使用TermRange无法查询
  47. //su.searchByTermRange("size",newNumericField("200").stringValue(),newNumericField("500").stringValue(),10);
  48. QueryParserparser=newQueryParser(Version.LUCENE_35,"size",analyzer);
  49. Queryquery;
  50. try{
  51. query=parser.parse("size:[100TO500]");
  52. su.searchByQueryParse(query,10);
  53. }catch(ParseExceptione){
  54. e.printStackTrace();
  55. }
  56. }
  57. @Test
  58. publicvoidsearchByNumRange(){
  59. //su.searchByNumricRange("attach",2,10,5);
  60. su.searchByNumricRange("size",100,300,10);
  61. }
  62. @Test
  63. publicvoidsearchByPrefix(){
  64. su.searchByPrefix("content","人",10);
  65. }
  66. @Test
  67. publicvoidsearchByWildcard(){
  68. //匹配@itat.org结尾的所有字符
  69. //su.searchByWildcard("email","*@itat.org",10);
  70. //匹配j开头的有三个字符的name
  71. //su.searchByWildcard("name","j???",10);
  72. su.searchByWildcard("content","类?",10);
  73. }
  74. @Test
  75. publicvoidsearchByBoolean(){
  76. su.searchByBoolean(10);
  77. }
  78. @Test
  79. publicvoidsearchByPhrase(){
  80. su.searchByPhrase(10);
  81. }
  82. @Test
  83. publicvoidsearchByFuzzy(){
  84. su.searchByFuzzy(10);
  85. }
  86. @Test
  87. publicvoidsearchByQueryParse()throwsParseException{
  88. //1、创建QueryParser对象,默认搜索域为content
  89. QueryParserparser=newQueryParser(Version.LUCENE_35,"content",newStandardAnalyzer(Version.LUCENE_35));
  90. //改变空格的默认操作符,以下可以改成AND
  91. //parser.setDefaultOperator(Operator.AND);
  92. //开启第一个字符的通配符匹配,默认关闭因为效率不高
  93. parser.setAllowLeadingWildcard(true);
  94. //搜索content中包含有like的
  95. Queryquery=parser.parse("like");
  96. //有basketball或者football的,空格默认就是OR
  97. query=parser.parse("basketballfootball");
  98. //改变搜索域为name为mike
  99. //query=parser.parse("content:like");
  100. //同样可以使用*和?来进行通配符匹配
  101. //query=parser.parse("name:j*");
  102. //通配符默认不能放在首位
  103. //query=parser.parse("email:*@itat.org");
  104. //匹配name中没有mike但是content中必须有football的,+和-要放置到域说明前面
  105. query=parser.parse("-name:mike+like");
  106. //匹配一个区间,注意:TO必须是大写
  107. //query=parser.parse("id:[1TO6]");
  108. //闭区间匹配只会匹配到2
  109. //query=parser.parse("id:{1TO3}");
  110. //完全匹配ILikeFootball的
  111. //query=parser.parse("\"Ilikefootball\"");
  112. //匹配I和football之间有一个单词距离的
  113. //query=parser.parse("\"Ifootball\"~1");
  114. //模糊查询
  115. //query=parser.parse("name:make~");
  116. //没有办法匹配数字范围(自己扩展Parser)
  117. //query=parser.parse("attach:[2TO10]");
  118. su.searchByQueryParse(query,10);
  119. }
  120. @Test
  121. publicvoidindexFile(){
  122. FileIndexUtils.index(true);
  123. }
  124. @Test
  125. publicvoidtestSearchPage01(){
  126. su.searchPage("java",2,5);
  127. System.out.println("-------------------------------");
  128. //su.searchNoPage("java");
  129. su.searchPageByAfter("java",2,2);
  130. }
  131. @Test
  132. publicvoidtestSearchPage02(){
  133. su.searchPageByAfter("java",3,20);
  134. }
  135. }

4、创建索引的类
  1. packageorg.itat.index;
  2. importjava.io.File;
  3. importjava.io.FileReader;
  4. importjava.io.IOException;
  5. importorg.apache.commons.io.FileUtils;
  6. importorg.apache.lucene.analysis.Analyzer;
  7. importorg.apache.lucene.analysis.standard.StandardAnalyzer;
  8. importorg.apache.lucene.document.Document;
  9. importorg.apache.lucene.document.Field;
  10. importorg.apache.lucene.document.NumericField;
  11. importorg.apache.lucene.index.CorruptIndexException;
  12. importorg.apache.lucene.index.IndexWriter;
  13. importorg.apache.lucene.index.IndexWriterConfig;
  14. importorg.apache.lucene.store.Directory;
  15. importorg.apache.lucene.store.FSDirectory;
  16. importorg.apache.lucene.store.LockObtainFailedException;
  17. importorg.apache.lucene.util.Version;
  18. importorg.wltea.analyzer.lucene.IKAnalyzer;
  19. publicclassFileIndexUtils{
  20. privatestaticDirectorydirectory=null;
  21. privatestaticAnalyzeranalyzer=newIKAnalyzer();
  22. static{
  23. try{
  24. directory=FSDirectory.open(newFile("F:\\Workspaces\\lucenes\\02_lucene_searcher\\index"));
  25. }catch(IOExceptione){
  26. e.printStackTrace();
  27. }
  28. }
  29. publicstaticDirectorygetDirectory(){
  30. returndirectory;
  31. }
  32. publicstaticvoidindex(booleanhasNew){
  33. IndexWriterwriter=null;
  34. try{
  35. writer=newIndexWriter(directory,newIndexWriterConfig(Version.LUCENE_35,analyzer));
  36. if(hasNew){
  37. writer.deleteAll();
  38. }
  39. Filefile=newFile("F:\\Workspaces\\lucenes\\02_lucene_searcher\\resource");
  40. Documentdoc=null;
  41. for(Filef:file.listFiles()){
  42. doc=newDocument();
  43. doc.add(newField("content",FileUtils.readFileToString(f),Field.Store.YES,Field.Index.ANALYZED));
  44. doc.add(newField("filename",f.getName(),Field.Store.YES,Field.Index.ANALYZED));
  45. doc.add(newField("path",f.getAbsolutePath(),Field.Store.YES,Field.Index.ANALYZED));
  46. doc.add(newNumericField("date",Field.Store.YES,true).setLongValue(f.lastModified()));
  47. doc.add(newNumericField("size",Field.Store.YES,true).setIntValue((int)(f.length())));
  48. writer.addDocument(doc);
  49. }
  50. }catch(CorruptIndexExceptione){
  51. e.printStackTrace();
  52. }catch(LockObtainFailedExceptione){
  53. e.printStackTrace();
  54. }catch(IOExceptione){
  55. e.printStackTrace();
  56. }finally{
  57. try{
  58. if(writer!=null)writer.close();
  59. }catch(CorruptIndexExceptione){
  60. e.printStackTrace();
  61. }catch(IOExceptione){
  62. e.printStackTrace();
  63. }
  64. }
  65. }
  66. }

5、对索引进行操作的类
  1. packageorg.itat.index;
  2. importjava.io.IOException;
  3. importjava.text.ParseException;
  4. importjava.text.SimpleDateFormat;
  5. importjava.util.Date;
  6. importjava.util.HashMap;
  7. importjava.util.Map;
  8. importorg.apache.lucene.analysis.standard.StandardAnalyzer;
  9. importorg.apache.lucene.document.Document;
  10. importorg.apache.lucene.document.Field;
  11. importorg.apache.lucene.document.NumericField;
  12. importorg.apache.lucene.index.CorruptIndexException;
  13. importorg.apache.lucene.index.IndexReader;
  14. importorg.apache.lucene.index.IndexWriter;
  15. importorg.apache.lucene.index.IndexWriterConfig;
  16. importorg.apache.lucene.index.StaleReaderException;
  17. importorg.apache.lucene.index.Term;
  18. importorg.apache.lucene.store.Directory;
  19. importorg.apache.lucene.store.LockObtainFailedException;
  20. importorg.apache.lucene.store.RAMDirectory;
  21. importorg.apache.lucene.util.Version;
  22. publicclassIndexUtil{
  23. privateString[]ids={"1","2","3","4","5","6"};
  24. privateString[]emails={"aa@itat.org","bb@itat.org","cc@cc.org","dd@sina.org","ee@zttc.edu","ff@itat.org"};
  25. privateString[]contents={
  26. "welcometovisitedthespace,Ilikebook",
  27. "helloboy,Ilikepingpengball",
  28. "mynameisccIlikegame",
  29. "Ilikefootball",
  30. "IlikefootballandIlikebasketballtoo",
  31. "Ilikemovieandswim"
  32. };
  33. privateDate[]dates=null;
  34. privateint[]attachs={2,3,1,4,5,5};
  35. privateString[]names={"zhangsan","lisi","john","jetty","mike","jake"};
  36. privateDirectorydirectory=null;
  37. privateMap<String,Float>scores=newHashMap<String,Float>();
  38. publicIndexUtil(){
  39. setDates();
  40. scores.put("itat.org",2.0f);
  41. scores.put("zttc.edu",1.5f);
  42. directory=newRAMDirectory();
  43. index();
  44. }
  45. privatevoidsetDates(){
  46. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  47. try{
  48. dates=newDate[ids.length];
  49. dates[0]=sdf.parse("2010-02-19");
  50. dates[1]=sdf.parse("2012-01-11");
  51. dates[2]=sdf.parse("2011-09-19");
  52. dates[3]=sdf.parse("2010-12-22");
  53. dates[4]=sdf.parse("2012-01-01");
  54. dates[5]=sdf.parse("2011-05-19");
  55. }catch(ParseExceptione){
  56. e.printStackTrace();
  57. }
  58. }
  59. publicvoidundelete(){
  60. //使用IndexReader进行恢复
  61. try{
  62. IndexReaderreader=IndexReader.open(directory,false);
  63. //恢复时,必须把IndexReader的只读(readOnly)设置为false
  64. reader.undeleteAll();
  65. reader.close();
  66. }catch(CorruptIndexExceptione){
  67. e.printStackTrace();
  68. }catch(StaleReaderExceptione){
  69. e.printStackTrace();
  70. }catch(LockObtainFailedExceptione){
  71. e.printStackTrace();
  72. }catch(IOExceptione){
  73. e.printStackTrace();
  74. }
  75. }
  76. publicvoidmerge(){
  77. IndexWriterwriter=null;
  78. try{
  79. writer=newIndexWriter(directory,
  80. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  81. //会将索引合并为2段,这两段中的被删除的数据会被清空
  82. //特别注意:此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,
  83. //Lucene会根据情况自动处理的
  84. writer.forceMerge(2);
  85. }catch(CorruptIndexExceptione){
  86. e.printStackTrace();
  87. }catch(LockObtainFailedExceptione){
  88. e.printStackTrace();
  89. }catch(IOExceptione){
  90. e.printStackTrace();
  91. }finally{
  92. try{
  93. if(writer!=null)writer.close();
  94. }catch(CorruptIndexExceptione){
  95. e.printStackTrace();
  96. }catch(IOExceptione){
  97. e.printStackTrace();
  98. }
  99. }
  100. }
  101. publicvoidforceDelete(){
  102. IndexWriterwriter=null;
  103. try{
  104. writer=newIndexWriter(directory,
  105. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  106. writer.forceMergeDeletes();
  107. }catch(CorruptIndexExceptione){
  108. e.printStackTrace();
  109. }catch(LockObtainFailedExceptione){
  110. e.printStackTrace();
  111. }catch(IOExceptione){
  112. e.printStackTrace();
  113. }finally{
  114. try{
  115. if(writer!=null)writer.close();
  116. }catch(CorruptIndexExceptione){
  117. e.printStackTrace();
  118. }catch(IOExceptione){
  119. e.printStackTrace();
  120. }
  121. }
  122. }
  123. publicvoiddelete(){
  124. IndexWriterwriter=null;
  125. try{
  126. writer=newIndexWriter(directory,
  127. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  128. //参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
  129. //此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
  130. writer.deleteDocuments(newTerm("id","1"));
  131. writer.commit();
  132. }catch(CorruptIndexExceptione){
  133. e.printStackTrace();
  134. }catch(LockObtainFailedExceptione){
  135. e.printStackTrace();
  136. }catch(IOExceptione){
  137. e.printStackTrace();
  138. }finally{
  139. try{
  140. if(writer!=null)writer.close();
  141. }catch(CorruptIndexExceptione){
  142. e.printStackTrace();
  143. }catch(IOExceptione){
  144. e.printStackTrace();
  145. }
  146. }
  147. }
  148. publicvoidupdate(){
  149. IndexWriterwriter=null;
  150. try{
  151. writer=newIndexWriter(directory,
  152. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  153. /*
  154. *Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集
  155. *先删除之后再添加
  156. */
  157. Documentdoc=newDocument();
  158. doc.add(newField("id","11",Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  159. doc.add(newField("email",emails[0],Field.Store.YES,Field.Index.NOT_ANALYZED));
  160. doc.add(newField("content",contents[0],Field.Store.NO,Field.Index.ANALYZED));
  161. doc.add(newField("name",names[0],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  162. writer.updateDocument(newTerm("id","1"),doc);
  163. }catch(CorruptIndexExceptione){
  164. e.printStackTrace();
  165. }catch(LockObtainFailedExceptione){
  166. e.printStackTrace();
  167. }catch(IOExceptione){
  168. e.printStackTrace();
  169. }finally{
  170. try{
  171. if(writer!=null)writer.close();
  172. }catch(CorruptIndexExceptione){
  173. e.printStackTrace();
  174. }catch(IOExceptione){
  175. e.printStackTrace();
  176. }
  177. }
  178. }
  179. publicvoidquery(){
  180. try{
  181. IndexReaderreader=IndexReader.open(directory);
  182. //通过reader可以有效的获取到文档的数量
  183. System.out.println("numDocs:"+reader.numDocs());
  184. System.out.println("maxDocs:"+reader.maxDoc());
  185. System.out.println("deleteDocs:"+reader.numDeletedDocs());
  186. reader.close();
  187. }catch(CorruptIndexExceptione){
  188. e.printStackTrace();
  189. }catch(IOExceptione){
  190. e.printStackTrace();
  191. }
  192. }
  193. publicvoidindex(){
  194. IndexWriterwriter=null;
  195. try{
  196. writer=newIndexWriter(directory,newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  197. writer.deleteAll();
  198. Documentdoc=null;
  199. for(inti=0;i<ids.length;i++){
  200. doc=newDocument();
  201. doc.add(newField("id",ids[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  202. doc.add(newField("email",emails[i],Field.Store.YES,Field.Index.NOT_ANALYZED));
  203. doc.add(newField("content",contents[i],Field.Store.NO,Field.Index.ANALYZED));
  204. doc.add(newField("name",names[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  205. //存储数字
  206. doc.add(newNumericField("attach",Field.Store.YES,true).setIntValue(attachs[i]));
  207. //存储日期
  208. doc.add(newNumericField("date",Field.Store.YES,true).setLongValue(dates[i].getTime()));
  209. Stringet=emails[i].substring(emails[i].lastIndexOf("@")+1);
  210. System.out.println(et);
  211. if(scores.containsKey(et)){
  212. doc.setBoost(scores.get(et));
  213. }else{
  214. doc.setBoost(0.5f);
  215. }
  216. writer.addDocument(doc);
  217. }
  218. }catch(CorruptIndexExceptione){
  219. e.printStackTrace();
  220. }catch(LockObtainFailedExceptione){
  221. e.printStackTrace();
  222. }catch(IOExceptione){
  223. e.printStackTrace();
  224. }finally{
  225. try{
  226. if(writer!=null)writer.close();
  227. }catch(CorruptIndexExceptione){
  228. e.printStackTrace();
  229. }catch(IOExceptione){
  230. e.printStackTrace();
  231. }
  232. }
  233. }
  234. }

工程下载地址:http://download.csdn.net/detail/wxwzy738/5256553

分享到:
评论

相关推荐

    lucene in action 第二版

    《Lucene in Action 第二版》是一本专门介绍如何使用Lucene搜索引擎框架的书籍。Lucene是一个高性能的全文检索库,它允许开发者在应用程序中实现搜索功能。第二版意味着这本书经过了更新,以适应Lucene版本的变化。...

    lucene第一步---6.分页

    本篇文章将带你迈出使用Lucene的第一步,重点关注如何实现分页检索,这对于构建高效、用户友好的搜索系统至关重要。 Lucene的核心功能包括文档索引、查询解析和结果排序。在分页检索方面,我们需要考虑如何有效地...

    Lucene实战(中文版第二版)对应Lucene版本

    《Lucene实战(中文版第二版)》是针对搜索引擎开发领域的经典著作,它详细介绍了如何使用Apache Lucene这个强大的全文搜索引擎库。Lucene是Java语言实现的开源项目,被广泛应用于各种信息检索系统中,包括网站搜索...

    lucene第一步---5.中文分词IKAnalyzer和高亮highlighter的使用

    标题中的“lucene第一步---5.中文分词IKAnalyzer和高亮highlighter的使用”指出,这个主题将探讨如何在Lucene中应用IKAnalyzer进行中文分词,以及如何使用高亮器(highlighter)来突出搜索结果中的关键词。Lucene是...

    lucene实战第二版(最新)

    本书《Lucene实战第二版》是一本关于如何使用Lucene进行文本检索的实用教程。这本书详细介绍了Lucene的使用方法和内部工作机制,并提供了丰富的代码示例和清晰的解释。它不仅适合那些计划在应用中使用Lucene的开发者...

    Lucene In Action 第二版 高清中文版+附书源代码

    《Lucene In Action 第二版》是一本深入探讨Apache Lucene全文搜索引擎库的专业书籍,高清中文版的提供为中文读者提供了便利。这本书由Michael McCandless等作者编写,旨在帮助开发者充分利用Lucene的强大功能,构建...

    lucene in action 2nd edition, lucene in action 第二版 PDF

    《Lucene in Action 第二版》是一本深入探讨Apache Lucene全文检索库的专业书籍,它在Java开发领域具有很高的权威性。这本书详细介绍了如何利用Lucene进行高效的文本搜索和索引构建,是Java开发者和信息检索爱好者的...

    Lucene实战中文版第2版

    经典的Lucene资源

    Lucene实战 第二版 完整清晰中文版

    Lucene实战第二版完整清晰中文版是一本介绍Lucene开源全文搜索引擎开发包的书籍。Lucene是一个用Java编写的功能强大的全文搜索引擎库,它以出色的可扩展性和快速的搜索特性获得了广泛的赞誉。本书详细介绍了如何有效...

    Lucene实战(第二版)

    《Lucene实战(第二版)》是一本深入探讨Apache Lucene全文搜索引擎库的权威书籍,主要面向对Java和搜索引擎技术感兴趣的开发者。这本书详尽地介绍了如何利用Lucene进行信息检索、文本分析和索引构建,同时也涵盖了...

    Lucene实战第二版中英文PDF(带书签)

    《Lucene实战第二版》是关于全文搜索引擎Lucene的一本权威指南,由Michael McCandless、Erik Hatcher和Dave Bollinger共同撰写。这本书详细介绍了如何使用Java库Lucene来构建高性能、可扩展的搜索功能。以下是该书的...

    lucene,lucene教程,lucene讲解

    第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。 public void add(Query query, BooleanClause.Occur occur) BooleanClause用于表示布尔查询子句关系的类,包括: BooleanClause.Occur.MUST,...

    Lucene in Action第二版(中文和英文)

    《Lucene in Action》第二版是一本专注于开源全文搜索引擎库Lucene的专业著作,由美国的Otis Gospodnetic和Erik Hatcher共同撰写。这本书深入浅出地讲解了如何利用Lucene进行高效的文本搜索和索引构建,是Java开发者...

    Lucene的原理完整版pdf

    5. **术语(Term)**:经过分词后的单个词或短语称为术语,是Lucene搜索的基本单位。 ### 二、Lucene工作流程 1. **创建索引**:首先,开发者需要创建一个`IndexWriter`实例,然后调用`addDocument()`方法添加文档...

    lucene 高级搜索项目

    **Lucene 高级搜索项目概述** Lucene 是一个高性能、全文检索库,它提供了文本分析、索引和搜索功能,被广泛应用于各种搜索引擎的构建。在这个“Lucene 高级搜索项目”中,我们将深入探讨如何利用Lucene实现附件...

    Lucene实战中文版第2版.pdf

    本书的第二版更新了与最新Lucene版本相关的技术,确保读者能掌握最前沿的搜索技术。 Lucene的核心功能包括索引构建、查询解析、搜索执行和结果排序。索引构建是Lucene的第一步,它将文本数据转换为可快速检索的结构...

    Lucene实战

    《Lucene实战(第2版)》基于Apache的Lucene 3.0,从Lucene核心、Lucene应用、案例分析3个方面详细系统地介绍了Lucene,包括认识Lucene、建立索引、为应用程序添加搜索功能、高级搜索技术、扩展搜索、使用Tika提取文本...

    LuceneInAction(第2版)_cn.pdf

     《Lucene实战(第2版)》基于Apache的Lucene 3.0,从Lucene核心、Lucene应用、案例分析3个方面详细系统地介绍了Lucene,包括认识Lucene、建立索引、为应用程序添加搜索功能、高级搜索技术、扩展搜索、使用Tika提取...

    搜索引擎Lucene+Heritrix(第二版)4

    《搜索引擎Lucene+Heritrix(第二版)4》是一本深入探讨搜索引擎技术的专业书籍,主要围绕两个核心组件——Lucene和Heritrix展开。Lucene是Apache软件基金会的一个开源全文检索库,而Heritrix则是一个网络爬虫工具,...

Global site tag (gtag.js) - Google Analytics