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

lucene第一步,lucene基础,索引创建

 
阅读更多

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


1、工程结构


2、索引创建时的属性:

Field.Store.YES或者NO(存储域选项)
设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原
设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完全还原(doc.get)

Field.Index(索引选项)
Index.ANALYZED:进行分词和索引,适用于标题、内容等
Index.NOT_ANALYZED:进行索引,但是不进行分词,如果身份证号,姓名,ID等,适用于精确搜索
Index.ANALYZED_NOT_NORMS:进行分词但是不存储norms信息,这个norms中包括了创建索引的时间和权值等信息
norms中存储了很多排序的信息,
Index.NOT_ANALYZED_NOT_NORMS:即不进行分词也不存储norms信息
Index.NO:不进行索引

3、lucene的增删改查类

  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.search.IndexSearcher;
  19. importorg.apache.lucene.search.ScoreDoc;
  20. importorg.apache.lucene.search.TermQuery;
  21. importorg.apache.lucene.search.TopDocs;
  22. importorg.apache.lucene.store.Directory;
  23. importorg.apache.lucene.store.LockObtainFailedException;
  24. importorg.apache.lucene.store.RAMDirectory;
  25. importorg.apache.lucene.util.Version;
  26. publicclassIndexUtil{
  27. privateString[]ids={"1","2","3","4","5","6"};
  28. privateString[]emails={"aa@itat.org","bb@itat.org","cc@cc.org","dd@sina.org","ee@zttc.edu","ff@itat.org"};
  29. privateString[]contents={
  30. "welcometovisitedthespace,Ilikebook",
  31. "helloboy,Ilikepingpengball",
  32. "mynameisccIlikegame",
  33. "Ilikefootball",
  34. "IlikefootballandIlikebasketballtoo",
  35. "Ilikemovieandswim"
  36. };
  37. privateDate[]dates=null;
  38. privateint[]attachs={2,3,1,4,5,5};
  39. privateString[]names={"zhangsan","lisi","john","jetty","mike","jake"};
  40. privateDirectorydirectory=null;
  41. privateMap<String,Float>scores=newHashMap<String,Float>();
  42. privatestaticIndexReaderreader=null;
  43. publicIndexUtil(){
  44. try{
  45. setDates();
  46. scores.put("itat.org",2.0f);
  47. scores.put("zttc.edu",1.5f);
  48. //directory=FSDirectory.open(newFile("d:/lucene/index02"));
  49. directory=newRAMDirectory();
  50. index();
  51. reader=IndexReader.open(directory,false);
  52. }catch(IOExceptione){
  53. e.printStackTrace();
  54. }
  55. }
  56. /**
  57. *对于IndexReader而言,反复使用Index.open打开会有很大的开销,所以一般在整个程序的生命周期中
  58. *只会打开一个IndexReader,通过这个IndexReader来创建不同的IndexSearcher,如果使用单例模式,
  59. *可能出现的问题有:
  60. *1、当使用Writer修改了索引之后不会更新信息,所以需要使用IndexReader.openIfChange方法操作
  61. *如果IndexWriter在创建完成之后,没有关闭,需要进行commit操作之后才能提交
  62. *@return
  63. */
  64. publicIndexSearchergetSearcher(){
  65. try{
  66. if(reader==null){
  67. reader=IndexReader.open(directory,false);
  68. }else{
  69. IndexReadertr=IndexReader.openIfChanged(reader);
  70. //如果原来的reader没改变,返回null
  71. //如果原来的reader改变,则更新为新的索引
  72. if(tr!=null){
  73. reader.close();
  74. reader=tr;
  75. }
  76. }
  77. returnnewIndexSearcher(reader);
  78. }catch(CorruptIndexExceptione){
  79. e.printStackTrace();
  80. }catch(IOExceptione){
  81. e.printStackTrace();
  82. }
  83. returnnull;
  84. }
  85. privatevoidsetDates(){
  86. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  87. try{
  88. dates=newDate[ids.length];
  89. dates[0]=sdf.parse("2010-02-19");
  90. dates[1]=sdf.parse("2012-01-11");
  91. dates[2]=sdf.parse("2011-09-19");
  92. dates[3]=sdf.parse("2010-12-22");
  93. dates[4]=sdf.parse("2012-01-01");
  94. dates[5]=sdf.parse("2011-05-19");
  95. }catch(ParseExceptione){
  96. e.printStackTrace();
  97. }
  98. }
  99. /**
  100. *把之前删除的索引数据进行恢复
  101. */
  102. publicvoidundelete(){
  103. //使用IndexReader进行恢复
  104. try{
  105. IndexReaderreader=IndexReader.open(directory,false);
  106. //恢复时,必须把IndexReader的只读(readOnly)设置为false
  107. reader.undeleteAll();
  108. reader.close();
  109. }catch(CorruptIndexExceptione){
  110. e.printStackTrace();
  111. }catch(StaleReaderExceptione){
  112. e.printStackTrace();
  113. }catch(LockObtainFailedExceptione){
  114. e.printStackTrace();
  115. }catch(IOExceptione){
  116. e.printStackTrace();
  117. }
  118. }
  119. /**
  120. *forceMerge是lucene3.5之前替代optimize方法的,其实只是改了个名称,因为优化的使效率变低
  121. *因为一到优化它就会全部更新索引,这个所涉及到的负载是很大的
  122. *所以改了个名称,不推荐使用,在做优化的时候会把索引回收站中的数据文件全部删除
  123. *lucene会在你写索引的时候根据你的索引的段越来越多会自动帮忙优化的,force是强制优化
  124. */
  125. publicvoidmerge(){
  126. IndexWriterwriter=null;
  127. try{
  128. writer=newIndexWriter(directory,
  129. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  130. //会将索引合并为2段,这两段中的被删除的数据会被清空
  131. //特别注意:此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,
  132. //Lucene会根据情况自动处理的
  133. writer.forceMerge(2);
  134. }catch(CorruptIndexExceptione){
  135. e.printStackTrace();
  136. }catch(LockObtainFailedExceptione){
  137. e.printStackTrace();
  138. }catch(IOExceptione){
  139. e.printStackTrace();
  140. }finally{
  141. try{
  142. if(writer!=null)writer.close();
  143. }catch(CorruptIndexExceptione){
  144. e.printStackTrace();
  145. }catch(IOExceptione){
  146. e.printStackTrace();
  147. }
  148. }
  149. }
  150. /**
  151. *假如你想要强制删除回收站的信息可以调用writer.forceMergeDeletes()这个方法,
  152. *但是这个方法不推荐使用,比较消耗内存,lucene会自动根据容量的大小删除所删除的文件
  153. */
  154. publicvoidforceDelete(){
  155. IndexWriterwriter=null;
  156. try{
  157. writer=newIndexWriter(directory,
  158. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  159. writer.forceMergeDeletes();
  160. }catch(CorruptIndexExceptione){
  161. e.printStackTrace();
  162. }catch(LockObtainFailedExceptione){
  163. e.printStackTrace();
  164. }catch(IOExceptione){
  165. e.printStackTrace();
  166. }finally{
  167. try{
  168. if(writer!=null)writer.close();
  169. }catch(CorruptIndexExceptione){
  170. e.printStackTrace();
  171. }catch(IOExceptione){
  172. e.printStackTrace();
  173. }
  174. }
  175. }
  176. /**
  177. *删除索引数据,默认不会完全删除,被放入索引回收站
  178. */
  179. publicvoiddelete(){
  180. IndexWriterwriter=null;
  181. try{
  182. writer=newIndexWriter(directory,
  183. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  184. //参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
  185. //此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
  186. //执行完这个操作,索引文件夹下就会多出一个名叫_0_1.del的文件,也就是删除的文件在这个文件中记录了
  187. writer.deleteDocuments(newTerm("id","1"));
  188. writer.commit();
  189. }catch(CorruptIndexExceptione){
  190. e.printStackTrace();
  191. }catch(LockObtainFailedExceptione){
  192. e.printStackTrace();
  193. }catch(IOExceptione){
  194. e.printStackTrace();
  195. }finally{
  196. try{
  197. if(writer!=null)writer.close();
  198. }catch(CorruptIndexExceptione){
  199. e.printStackTrace();
  200. }catch(IOExceptione){
  201. e.printStackTrace();
  202. }
  203. }
  204. }
  205. /**
  206. *使用reader删除,其实里面也会调用writer删除,
  207. *优点是使用reader删除马上会更新索引信息
  208. *现在一般还是使用writer来删除,reader.getWriter这个方法被过时了
  209. */
  210. publicvoiddelete02(){
  211. try{
  212. reader.deleteDocuments(newTerm("id","1"));
  213. }catch(CorruptIndexExceptione){
  214. e.printStackTrace();
  215. }catch(LockObtainFailedExceptione){
  216. e.printStackTrace();
  217. }catch(IOExceptione){
  218. e.printStackTrace();
  219. }
  220. }
  221. /**
  222. *更新操作
  223. *Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集
  224. *先删除之后再添加
  225. */
  226. publicvoidupdate(){
  227. IndexWriterwriter=null;
  228. try{
  229. writer=newIndexWriter(directory,
  230. newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  231. Documentdoc=newDocument();
  232. doc.add(newField("id","11",Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  233. doc.add(newField("email",emails[0],Field.Store.YES,Field.Index.NOT_ANALYZED));
  234. doc.add(newField("content",contents[0],Field.Store.NO,Field.Index.ANALYZED));
  235. doc.add(newField("name",names[0],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  236. writer.updateDocument(newTerm("id","1"),doc);
  237. }catch(CorruptIndexExceptione){
  238. e.printStackTrace();
  239. }catch(LockObtainFailedExceptione){
  240. e.printStackTrace();
  241. }catch(IOExceptione){
  242. e.printStackTrace();
  243. }finally{
  244. try{
  245. if(writer!=null)writer.close();
  246. }catch(CorruptIndexExceptione){
  247. e.printStackTrace();
  248. }catch(IOExceptione){
  249. e.printStackTrace();
  250. }
  251. }
  252. }
  253. publicvoidquery(){
  254. try{
  255. IndexReaderreader=IndexReader.open(directory);
  256. //通过reader可以有效的获取到文档的数量
  257. System.out.println("numDocs:"+reader.numDocs());//存储的文档数//不包括被删除的
  258. System.out.println("maxDocs:"+reader.maxDoc());//总存储量,包括在回收站中的索引
  259. System.out.println("deleteDocs:"+reader.numDeletedDocs());
  260. reader.close();
  261. }catch(CorruptIndexExceptione){
  262. e.printStackTrace();
  263. }catch(IOExceptione){
  264. e.printStackTrace();
  265. }
  266. }
  267. /**
  268. *索引文件后缀为.fmn为保存的是域的名称等
  269. *.fdt和.fdx保存的是Store.YES的信息,保存域里面存储的数据
  270. *.frq表示这里的域哪些出现多少次,哪些单词出现多少次,
  271. *.nrm存储一些评分信息
  272. *.prx存储一些偏移量等
  273. *.tii和.tis专门存储索引里面的所有内容信息
  274. */
  275. publicvoidindex(){
  276. IndexWriterwriter=null;
  277. try{
  278. //在2.9版本之后,lucene的就不是全部的索引格式都兼容的了,所以在使用的时候必须写明版本号
  279. writer=newIndexWriter(directory,newIndexWriterConfig(Version.LUCENE_35,newStandardAnalyzer(Version.LUCENE_35)));
  280. writer.deleteAll();//清空索引
  281. Documentdoc=null;
  282. for(inti=0;i<ids.length;i++){
  283. doc=newDocument();
  284. doc.add(newField("id",ids[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  285. doc.add(newField("email",emails[i],Field.Store.YES,Field.Index.NOT_ANALYZED));
  286. doc.add(newField("email","test"+i+"@test.com",Field.Store.YES,Field.Index.NOT_ANALYZED));
  287. doc.add(newField("content",contents[i],Field.Store.NO,Field.Index.ANALYZED));
  288. doc.add(newField("name",names[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
  289. //存储数字
  290. //NumberTools.stringToLong("");已经被标记为过时了
  291. doc.add(newNumericField("attach",Field.Store.YES,true).setIntValue(attachs[i]));
  292. //存储日期
  293. doc.add(newNumericField("date",Field.Store.YES,true).setLongValue(dates[i].getTime()));
  294. Stringet=emails[i].substring(emails[i].lastIndexOf("@")+1);
  295. System.out.println(et);
  296. if(scores.containsKey(et)){
  297. doc.setBoost(scores.get(et));
  298. }else{
  299. doc.setBoost(0.5f);//默认是1.0f
  300. }
  301. writer.addDocument(doc);
  302. }
  303. }catch(CorruptIndexExceptione){
  304. e.printStackTrace();
  305. }catch(LockObtainFailedExceptione){
  306. e.printStackTrace();
  307. }catch(IOExceptione){
  308. e.printStackTrace();
  309. }finally{
  310. try{
  311. if(writer!=null)writer.close();
  312. }catch(CorruptIndexExceptione){
  313. e.printStackTrace();
  314. }catch(IOExceptione){
  315. e.printStackTrace();
  316. }
  317. }
  318. }
  319. publicvoidsearch01(){
  320. try{
  321. IndexReaderreader=IndexReader.open(directory);
  322. IndexSearchersearcher=newIndexSearcher(reader);
  323. TermQueryquery=newTermQuery(newTerm("email","test0@test.com"));
  324. TopDocstds=searcher.search(query,10);
  325. for(ScoreDocsd:tds.scoreDocs){
  326. Documentdoc=searcher.doc(sd.doc);
  327. System.out.println("("+sd.doc+"-"+doc.getBoost()+"-"+sd.score+")"+
  328. doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
  329. doc.get("attach")+","+doc.get("date")+","+doc.getValues("email")[1]);
  330. }
  331. reader.close();
  332. }catch(CorruptIndexExceptione){
  333. e.printStackTrace();
  334. }catch(IOExceptione){
  335. e.printStackTrace();
  336. }
  337. }
  338. publicvoidsearch02(){
  339. try{
  340. IndexSearchersearcher=getSearcher();
  341. TermQueryquery=newTermQuery(newTerm("content","like"));
  342. TopDocstds=searcher.search(query,10);
  343. for(ScoreDocsd:tds.scoreDocs){
  344. Documentdoc=searcher.doc(sd.doc);
  345. System.out.println(doc.get("id")+"---->"+
  346. doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
  347. doc.get("attach")+","+doc.get("date")+","+doc.getValues("email")[1]);
  348. }
  349. searcher.close();
  350. }catch(CorruptIndexExceptione){
  351. e.printStackTrace();
  352. }catch(IOExceptione){
  353. e.printStackTrace();
  354. }
  355. }
  356. }
4、lucene的单元测试类
  1. packageorg.itat.test;
  2. importorg.itat.index.IndexUtil;
  3. importorg.junit.Test;
  4. publicclassTestIndex{
  5. @Test
  6. publicvoidtestIndex(){
  7. IndexUtiliu=newIndexUtil();
  8. iu.index();
  9. }
  10. @Test
  11. publicvoidtestQuery(){
  12. IndexUtiliu=newIndexUtil();
  13. iu.query();
  14. }
  15. @Test
  16. publicvoidtestDelete(){
  17. IndexUtiliu=newIndexUtil();
  18. iu.delete();
  19. }
  20. @Test
  21. publicvoidtestDelete02(){
  22. IndexUtiliu=newIndexUtil();
  23. iu.delete02();
  24. }
  25. @Test
  26. publicvoidtestUnDelete(){
  27. IndexUtiliu=newIndexUtil();
  28. iu.undelete();
  29. }
  30. @Test
  31. publicvoidtestForceDelete(){
  32. IndexUtiliu=newIndexUtil();
  33. iu.forceDelete();
  34. }
  35. @Test
  36. publicvoidtestMerge(){
  37. IndexUtiliu=newIndexUtil();
  38. iu.merge();
  39. }
  40. @Test
  41. publicvoidtestUpdate(){
  42. IndexUtiliu=newIndexUtil();
  43. iu.update();
  44. }
  45. @Test
  46. publicvoidtestSearch01(){
  47. IndexUtiliu=newIndexUtil();
  48. iu.search01();
  49. }
  50. @Test
  51. publicvoidtestSearch02(){
  52. IndexUtiliu=newIndexUtil();
  53. for(inti=0;i<5;i++){
  54. iu.search02();
  55. System.out.println("-----------------------------");
  56. try{
  57. Thread.sleep(10000);
  58. }catch(InterruptedExceptione){
  59. e.printStackTrace();
  60. }
  61. }
  62. }
  63. }
分享到:
评论

相关推荐

    Lucene 索引的简单使用

    - **分词器(Tokenizer)**:分词器将输入的文本分解为一系列的词语,这是建立索引的第一步。 - **分析器(Analyzer)**:分析器结合了分词器、过滤器等,负责对文本进行预处理,如去除停用词、词形还原等。 ### 2...

    lucene第一步---6.分页

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

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

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

    java全文搜索引擎 Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便

    当使用Lucene时,第一步是进行文本分析。Lucene内置了多种Analyzer类,如StandardAnalyzer,用于处理常见的文本清洗和分词任务。分词是将输入文本拆分成独立的词汇单元,这些单元称为“术语”或“Token”。分词器会...

    基于lucene的索引与搜索

    网络机器人是搜索引擎的第一步,它们自动地遍历互联网,抓取网页内容。Lucene本身并不包含网络爬虫功能,但可以与其他爬虫框架如Nutch或Heritrix结合,以获取网页内容并将其送入Lucene进行处理。 2.2.2 索引与搜索 ...

    lucene创建修改删除组合条件查询

    首先,**创建索引**是使用Lucene的第一步。创建索引涉及到读取数据源(如文件或数据库),解析内容,然后将这些内容转换为Lucene可以理解的文档结构。每个文档由一个或多个字段组成,每个字段都有其特定的类型(如...

    第一个lucene程序

    1. **创建索引**:这是Lucene工作的第一步,它会把文档内容解析成一系列的术语(tokens),然后为每个术语建立倒排索引。倒排索引是一种数据结构,它允许快速查找包含特定术语的文档。 2. **索引写入**:在创建索引...

    Lucene.NET全文索引搜索Demo项目

    在项目中,"创建索引"是第一步。这通常涉及读取数据源(如数据库、文件或网页)中的内容,将文本字段拆分成单词(称为分词),并为每个单词创建索引条目。这个过程称为索引构建。项目中可能使用了IKAnalyzerNet,这...

    lucene3源码分析

    - **索引构建**:这是全文检索的第一步,涉及到将文档内容转换为可被快速搜索的形式。 - **查询处理**:当用户提交查询时,系统会根据已建立的索引执行相应的搜索逻辑。 - **相关性评分**:为了提供最相关的搜索结果...

    Lucene全文检索引擎

    5. **分词器(Tokenizer)**:用于将输入的文本分解成一系列的词或短语,是文本分析的第一步。 6. **查询解析器(Query Parser)**:处理用户的搜索请求,将其转化为Lucene可以理解的查询对象。 7. **评分...

    Lucene4.10.3索引+查询

    - **分词器(Tokenizer)**:将输入文本分解成独立的词语,这是建立索引的第一步。 - **搜索器(Searcher)**:负责执行查询,返回匹配结果。 - **查询解析器(Query Parser)**:将用户的查询字符串转化为Lucene...

    lucene5.3.1增删改查

    创建索引是Lucene的第一步,它将文档内容转换为可搜索的结构。这个过程涉及到以下步骤: 1. **初始化Analyzer**: Analyzer负责对输入文本进行分词,根据语言特性进行标准化处理。例如,对于英文,可以使用...

    LUCENE索引搜索数据库技术汇总

    - **分词器(Tokenizer)**: 分词器将输入文本分割成独立的词语,这是建立索引的第一步。 - **分析器(Analyzer)**: 分析器包含分词器和其他过滤器,负责对文本进行预处理,如去除停用词、词干提取等。 2. **...

    Lucene测试程序3.5

    首先,建立索引是Lucene工作流程中的第一步。索引是Lucene为了快速查找文档而创建的一种数据结构。在Lucene 3.5中,我们通常会使用`IndexWriter`类来创建或更新索引。这个过程包括读取源文档,使用分词器(Analyzer...

    lucene 3.4基本应用

    在Lucene中,建立索引是搜索的第一步。首先,我们需要创建一个`IndexWriter`实例,这是负责写入索引的主要类。`IndexWriter`配置包括分词器(Tokenizer)、分析器(Analyzer)和目录(Directory)。分词器将文档内容...

    LUCENE的搜索引擎例子

    1. **索引创建**:这是搜索引擎的第一步,我们需要遍历要索引的数据源(例如文件系统、数据库等),读取内容,并使用Lucene的Analyzer进行分词,然后创建Term(词项)和Document(文档)。Analyzer是负责文本分析的...

    lucene2.9开发指南

    - **建立索引**:这是Lucene搜索的第一步,涉及将数据转换为可搜索的索引结构。这通常包括读取数据源(如文件或数据库),然后将内容解析为文档,并使用分析器对文档内容进行分词。 - **搜索索引**:一旦索引建立...

    lucene 索引工具源码(桌面版)

    1. **分词器(Tokenizer)**:分词器是处理文本的第一步,它将文档拆分成可搜索的词元(tokens)。对于不同的语言,Lucene 提供了相应的分词器,例如,对于中文,可能会使用 IK 分词器或 HanLP 进行分词;对于英文,...

    lucene 网页抓取,模拟搜索引擎

    网页抓取是搜索引擎的第一步,它涉及到从互联网上获取信息。在Lucene项目中,通常会使用像Jsoup或HtmlUnit这样的第三方库来解析和提取网页内容。这些库能够解析HTML文档,提取出我们需要的文本,如文章内容、标题和...

    Lucene 常用功能介绍视频详解

    创建索引是Lucene工作的第一步。通过`Directory`接口,如`FSDirectory`,Lucene可以读写文件系统中的索引。`IndexWriter`类负责实际的索引构建过程,它允许添加、删除和更新文档。每个文档由一系列字段(Field)...

Global site tag (gtag.js) - Google Analytics