3.创建和维护索引库(Lucene6.0.0 CRUD)
2017-05-21 21:32
239 查看
项目源码:https://github.com/tangxing1993/lucene
效果展示:
效果展示:
结果:
通过结果发现。使用IntPoint和LongPoint并没有把数据存放到索引库中,所以查询到的结果为null
索引int类型的值不存储不排序
FloatPoint
索引float类型的值不存储不排序
DoublePoint
索引Double类型的值不存储不排序
BinaryDocValuesField
只存储不共享,例如标题类字段,如果需要共享并排序,推荐使用
NumericDocValuesField
存储long型字段,用于评分、排序和值检索,如果需要存储值,还需要添加一个单独的StoredField实例
SortedDocValuesField
索引并存储,用于String类型的Field排序,需要在StringField后添加同名的SortedDocValuesField
StringField
只索引但不分词,所有的字符串会作为一个整体进行索引,例如通常用于country或id等
TextField
索引并分词,不包括term vectors,例如通常用于一个body Field
StoredField
存储Field的值,可以用 IndexSearcher.doc和IndexReader.document来获取存储的Field和存储的值
3.1 创建和更新索引
Lucene给我们提供了创建和更新索引的API,在生成索引的过程中涉及到以下几个类。 IndexWriter>Document>Field>Analyzer Field 域对象,存在与文档内。通用接口IndexField,field是一个抽象域对象。StringField不分词完全存入到索引库中,TextField 进行分词,并且索引
创建索引
索引一般存放在硬盘的某个路径下,我们可以使用IndexWriter来创建一个索引库,IndexWriter对象的相关参数有:索引路径和配置信息,创建完索引库后要把索引文档放入到索引库中,索引文档包含要索引的域信息。
/** * 创建索引 */ public void createIndex(){ long startTime = System.currentTimeMillis(); //索引的创建时间 System.out.println("start index ... "); IndexWriter writer = null; Document document = null; try{ IndexWriterConfig config = new IndexWriterConfig(analyzer); writer = new IndexWriter(directory, config); writer.deleteAll(); /** * 这里为了提高索引的速度,我们重用field对象,而不是每次创建新的,可以节省GC的消耗时间 * Field是intPoint/StringField/TextField/longPoint等的父类 * 我们可以根据数据类型的需要选择合适的field对象 */ IntPoint iPoint = new IntPoint("id", 0); StringField sField = new StringField("name","", Store.YES); TextField tField = new TextField("content", "", Store.YES); LongPoint lPoint = new LongPoint("date", 0); for(int i=0;i<ids.length;i++){ document = new Document(); iPoint.setIntValue(ids[i]); document.add(iPoint); sField.setStringValue(names[i]); document.add(sField); tField.setStringValue(contents[i]); document.add(tField); lPoint.setLongValue(dates[i].getTime()); document.add(lPoint); writer.addDocument(document); } long endTime = System.currentTimeMillis();//索引的结束时间 System.out.println("end index !!!"); System.out.println("times:"+(endTime-startTime)+"ms"); }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=writer){ try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
更新索引
Lucene更新索引文档是先删除旧的文档信息,然后把新的文档写入到索引库中。用到的方法是IndexWriter.updateDocument,传入的参数为term,要删除的文档term信息,第二个参数为新的文档信息
/** * 更新索引对象 早期的版本中先通过IndexReader删除文档 再使用IndexWriter写入更新后的文档 * 新版本中我们可以通过先查找出要修改的旧文档,然后改变要改动的列,最后updateDocument */ public void updateIndex(){ IndexWriter writer = null; Document document = null; try{ System.out.println("开始更新..."); writer = new IndexWriter(directory,new IndexWriterConfig(analyzer)); IndexSearcher search = new IndexSearcher(this.getIndexReader()); Query query = new QueryParser("name", analyzer).parse("aa"); TopDocs topDocs = search.search(query, 10); ScoreDoc[] scoreDocs = topDocs.scoreDocs; if(scoreDocs.length==0){ throw new IllegalArgumentException("索引中没有匹配结果..."); }else if(scoreDocs.length>1){ throw new IllegalArgumentException("索引匹配多个结果..."); }else{ //获取旧文档 document = search.doc(scoreDocs[0].doc); //先删除要改变的旧列 document.removeFields("name"); document.add(new StringField("name","update",Store.YES)); //term是搜索语法的最小单位 这里的更新是先删除在更新 删除的对象放在索引回收站里面 数据还可以恢复 writer.updateDocument(new Term("name","aa"), document); } System.out.println("文档更新成功!"); }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=writer){ try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
效果展示:
索引库的删除
lucene使用IndexWriter来删除索引文档
public void delete(){ IndexWriter writer =null; try{ writer = new IndexWriter(directory, new IndexWriterConfig(analyzer)); //TermQuery 精确的查询方法 writer.deleteDocuments(new TermQuery(new Term("name", "bb"))); }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=writer){ try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
效果展示:
简单的索引查询
Lucene使用IndexSearch来执行查询的所有操作,需要参数:索引库的字符流对象。lucene运用search方法查询出具有相关度的数据,然后我们按照评分取出。TopDocs具有相关度的文档,ScoreDocs文档评分数组
public void doSearch(){ IndexSearcher search = null; try{ search = new IndexSearcher(this.getIndexReader()); //创建查询解析器 QueryParser parse = new QueryParser("content", analyzer); //获取查询对象 Query query = parse.parse("like"); //搜索索引库返回最相关的10条数据 TopDocs topDocs = search.search(query, 10);//第二个参数为搜索显示的记录数 //从topDocs中取出查询结果 ScoreDoc[] sds = topDocs.scoreDocs; for(ScoreDoc sd : sds){ //获取结果文档信息 Document doc = search.doc(sd.doc); System.out.println("docID:"+sd.doc+" | id:"+doc.get("id")+" | " + "name:"+doc.get("name")+" | content:"+doc.get("content")+" | date:"+doc.get("date")); } }catch(Exception e){ e.printStackTrace(); } }
结果:
通过结果发现。使用IntPoint和LongPoint并没有把数据存放到索引库中,所以查询到的结果为null
Field总结
IntPoint索引int类型的值不存储不排序
FloatPoint
索引float类型的值不存储不排序
DoublePoint
索引Double类型的值不存储不排序
BinaryDocValuesField
只存储不共享,例如标题类字段,如果需要共享并排序,推荐使用
NumericDocValuesField
存储long型字段,用于评分、排序和值检索,如果需要存储值,还需要添加一个单独的StoredField实例
SortedDocValuesField
索引并存储,用于String类型的Field排序,需要在StringField后添加同名的SortedDocValuesField
StringField
只索引但不分词,所有的字符串会作为一个整体进行索引,例如通常用于country或id等
TextField
索引并分词,不包括term vectors,例如通常用于一个body Field
StoredField
存储Field的值,可以用 IndexSearcher.doc和IndexReader.document来获取存储的Field和存储的值
相关文章推荐
- 第60天(就业班) Lucene入门、创建索引库、CRUD
- lucene&solr从入门到精通-----创建索引,写到索引库
- 【示例】Lucene创建索引库编程步骤
- 全文检索Lucene(二)---索引库维护
- 1 Lucene笔记(一):创建索引库、根据关键字搜索
- Lucene-索引库的CRUD
- 使用Lucene开发简单的站内新闻搜索引擎(索引库的创建)
- lucene功能四;索引库的维护;索引库的添加;修改;删除;及代码实现;代码示例
- Lucene&Solr(之二)-索引库CRUD、Solr的安装
- Lucene创建和查询索引库的HelloWorld(含详细注释)
- Lucene 3.6.1:中文分词、创建索引库、排序、多字段分页查询以及高亮显示
- 全文检索之lucene的优化篇--创建索引库
- 【Lucene】创建第一个Lucene索引库
- 【Lucene】使用反射技术优化Lucene索引库的查询与创建
- 全文检索之lucene的优化篇--创建索引库
- JAVAWEB开发之Lucene详解——Lucene入门及使用场景、全文检索、索引CRUD、优化索引库、分词器、高亮、相关度排序、各种查询
- Lucene 6.10 初级 创建索引库和利用索引库进行搜索!
- SQL Server Database 维护计划创建完整的备份策略
- Lucene 查询索引库
- Lucene 索引创建