java 创建索引_lucene创建索引的几种方式(一)

本文介绍了使用Lucene在Java中创建索引的两种方法:一是通过文件生成索引,涉及FSDirectory、IndexWriter和StandardAnalyzer等;二是按字段创建索引,展示了如何添加文档、删除和更新索引。
摘要由CSDN通过智能技术生成

什么是索引:

根据你输入的值去找,这个值就是索引

第一种创建索引的方式:

根据文件来生成索引,如后缀为.txt等的文件

步骤:

第一步:FSDirectory.open(Paths.get(url));根据路径获取存储索引的目录。

FSDirectory:表示对文件系统目录的操作。RAMDirectory :内存中的目录操作。

Paths为NIO(new io)的一个类;Path 类是 java.io.File 类的升级版,File file=newFile("index.html")而Path path=Paths.get("index.html");由于 Path 类基于字符串创建,因此它引用的资源也有可能不存在。

关于nio:传统的io流都是通过字节的移动来处理的,也就是说输入/输出流一次只能处理一个字节,因此面向流的输入/输出系统通常效率不高;因此引进了新IO(new IO),NIO采用内存映射文件的方式来处理输入/输出,NIO将文件或文件的一段区域映射到内存中,这样就可以向访问内存一样来访问文件了(这种方式模拟了操作系统上的虚拟内存的概念),所以NIO的效率很快。

第二步:new IndexWriter(Directory,IndexWriterConfig)创建索引

第三步:索引指定目录的文件

第四步:将文件写入lucene中的文档(Document)

packagecom.wp.util;importjava.io.File;importjava.io.FileReader;importjava.nio.file.Paths;importorg.apache.lucene.analysis.Analyzer;importorg.apache.lucene.analysis.standard.StandardAnalyzer;importorg.apache.lucene.document.Document;importorg.apache.lucene.document.Field;importorg.apache.lucene.document.TextField;importorg.apache.lucene.index.IndexWriter;importorg.apache.lucene.index.IndexWriterConfig;importorg.apache.lucene.store.Directory;importorg.apache.lucene.store.FSDirectory;public classIndexer {private IndexWriter writer; //写索引实例

/*** 构造方法 实例化IndexWriter

*

*@paramindexDir

*@throwsException*/

public Indexer(String indexDir) throwsException {

Directory dir= FSDirectory.open(Paths.get(indexDir));//根据路径获取存储索引的目录

Analyzer analyzer = new StandardAnalyzer(); //这里用了多态,StandardAnalyzer是标准分词器,Analyzer是一个分词器

IndexWriterConfig iwc = newIndexWriterConfig(analyzer); writer= newIndexWriter(dir, iwc); }/*** 关闭写索引 * *@throwsException*/ public void close() throwsException { writer.close(); }/*** 索引指定目录的所有文件 * *@paramdataDir *@throwsException*/ public int index(String dataDir) throwsException { File[] files= newFile(dataDir).listFiles();for(File f : files) { indexFile(f); }returnwriter.numDocs(); }/*** 索引指定文件 * *@paramf*/ private void indexFile(File f) throwsException {//关于f.getCanonicalPath()查看http://www.blogjava.net/dreamstone/archive/2007/08/08/134968.html System.out.println("索引文件:" +f.getCanonicalPath()); Document doc=getDocument(f); writer.addDocument(doc); }/*** 获取文档,文档里再设置每个字段 * *@paramf*/ private Document getDocument(File f) throwsException { Document doc= newDocument(); doc.add(new TextField("contents", newFileReader(f))); doc.add(new TextField("fileName", f.getName(), Field.Store.YES)); doc .add(new TextField("fullPath", f.getCanonicalPath(), Field.Store.YES));returndoc; }public static voidmain(String[] args) { String indexDir= "D:\\lucene4"; String dataDir= "D:\\lucene4\\data"; Indexer indexer= null;int numIndexed = 0;long start =System.currentTimeMillis();try{ indexer= newIndexer(indexDir); numIndexed=indexer.index(dataDir); }catch(Exception e) { e.printStackTrace(); }finally{try{ indexer.close(); }catch(Exception e) { e.printStackTrace(); } }long end =System.currentTimeMillis(); System.out.println("索引:" + numIndexed + " 个文件 花费了" + (end -start)+ " 毫秒"); } }

第二种创建索引的方式:

根据字段来生成索引,我用的是数组

第一步:创建索引

第二步:将字段添加到文档中

packagecom.wp.util;importjava.nio.file.Paths;importorg.apache.lucene.analysis.Analyzer;importorg.apache.lucene.analysis.standard.StandardAnalyzer;importorg.apache.lucene.document.Document;importorg.apache.lucene.document.Field;importorg.apache.lucene.document.StringField;importorg.apache.lucene.document.TextField;importorg.apache.lucene.index.DirectoryReader;importorg.apache.lucene.index.IndexReader;importorg.apache.lucene.index.IndexWriter;importorg.apache.lucene.index.IndexWriterConfig;importorg.apache.lucene.index.Term;importorg.apache.lucene.store.Directory;importorg.apache.lucene.store.FSDirectory;importorg.junit.Before;importorg.junit.Test;public classIndexIngTest {private String ids[] = { "1", "2", "3"};private String citys[] = { "qingdao", "nanjing", "shanghai"};private String descs[] = { "Qingdao is a beautiful city.","Nanjing is a city of culture.", "Shanghai is a bustling city."};private Directory dir;//目录

/*** 获取IndexWriter实例

*

*@return*@throwsException*/

private IndexWriter getWriter() throwsException {

Analyzer analyzer= new StandardAnalyzer(); //标准分词器

IndexWriterConfig iwc = newIndexWriterConfig(analyzer);

IndexWriter writer= newIndexWriter(dir, iwc);returnwriter;

}/*** 添加文档

*

*@throwsException*/@Beforepublic void setUp() throwsException {

dir= FSDirectory.open(Paths.get("D:\\lucene\\luceneIndex"));//得到luceneIndex目录

IndexWriter writer = getWriter();//得到索引

for (int i = 0; i < ids.length; i++) {

Document doc= new Document();//创建文档

doc.add(new StringField("id", ids[i], Field.Store.YES));//将id属性存入内存中

doc.add(new StringField("city", citys[i], Field.Store.YES));

doc.add(new TextField("desc", descs[i], Field.Store.NO));

writer.addDocument(doc);//添加文档

}

writer.close();

}/*** 测试写了几个文档

*

*@throwsException*/@Testpublic void testIndexWriter() throwsException {

IndexWriter writer=getWriter();

System.out.println("写入了" + writer.numDocs() + "个文档");

writer.close();

}/*** 测试读取文档

*

*@throwsException*/@Testpublic void testIndexReader() throwsException {

IndexReader reader=DirectoryReader.open(dir);

System.out.println("最大文档数:" +reader.maxDoc());

System.out.println("实际文档数:" +reader.numDocs());

reader.close();

}/*** 测试删除 在合并前

*

*@throwsException*/@Testpublic void testDeleteBeforeMerge() throwsException {

IndexWriter writer=getWriter();

System.out.println("删除前:" +writer.numDocs());

writer.deleteDocuments(new Term("id", "1"));//term:根据id找到为1的

writer.commit();

System.out.println("writer.maxDoc():" +writer.maxDoc());

System.out.println("writer.numDocs():" +writer.numDocs());

writer.close();

}/*** 测试删除 在合并后

*

*@throwsException*/@Testpublic void testDeleteAfterMerge() throwsException {

IndexWriter writer=getWriter();

System.out.println("删除前:" +writer.numDocs());

writer.deleteDocuments(new Term("id", "1"));

writer.forceMergeDeletes();//强制删除

writer.commit();

System.out.println("writer.maxDoc():" +writer.maxDoc());

System.out.println("writer.numDocs():" +writer.numDocs());

writer.close();

}/*** 测试更新

*

*@throwsException*/@Testpublic void testUpdate() throwsException {

IndexWriter writer=getWriter();

Document doc= newDocument();

doc.add(new StringField("id", "1", Field.Store.YES));

doc.add(new StringField("city", "qingdao", Field.Store.YES));

doc.add(new TextField("desc", "dsss is a city.", Field.Store.NO));

writer.updateDocument(new Term("id", "1"), doc);

writer.close();

}

}

生成的索引文件如下:

b0a5eb76458cc8386b2a0b14095b2c5d.png

关于索引的搜索:

这里有一个要注意的地方:一定要先创建出索引后才能去进行查找,否则会报

org.apache.lucene.index.IndexNotFoundException:

no segments* file found in MMapDirectory@D:\lucene lockFactory=org.apache.lucene.store.NativeFSLockFactory@753f67a9: files: [data, lucene-5.3.1, lucene-5.3.1.zip]

packagecom.wp.lucene;importjava.nio.file.Paths;importorg.apache.lucene.analysis.Analyzer;importorg.apache.lucene.analysis.standard.StandardAnalyzer;importorg.apache.lucene.document.Document;importorg.apache.lucene.index.DirectoryReader;importorg.apache.lucene.index.IndexReader;importorg.apache.lucene.queryparser.classic.QueryParser;importorg.apache.lucene.search.IndexSearcher;importorg.apache.lucene.search.Query;importorg.apache.lucene.search.ScoreDoc;importorg.apache.lucene.search.TopDocs;importorg.apache.lucene.store.Directory;importorg.apache.lucene.store.FSDirectory;public classSearcher {/***

*@paramindexDir

* 哪个目录

*@paramq

* 要查询的字段

*@throwsException*/

public static void search(String indexDir, String q) throwsException {

Directory dir= FSDirectory.open(Paths.get(indexDir));//打开目录

IndexReader reader = DirectoryReader.open(dir);//进行读取

IndexSearcher is = new IndexSearcher(reader);//索引查询器

Analyzer analyzer = new StandardAnalyzer(); //标准分词器

QueryParser parser = new QueryParser("contents", analyzer);//在哪查询,第一个参数为查询的Document,在Indexer中创建了

Query query = parser.parse(q);//对字段进行解析后返回给查询

long start =System.currentTimeMillis();

TopDocs hits= is.search(query, 10);//开始查询,10代表前10条数据;返回一个文档

long end =System.currentTimeMillis();

System.out.println("匹配 " + q + " ,总共花费" + (end - start) + "毫秒" + "查询到"

+ hits.totalHits + "个记录");for(ScoreDoc scoreDoc : hits.scoreDocs) {

Document doc= is.doc(scoreDoc.doc);//根据文档的标识获取文档

System.out.println(doc.get("fullPath"));

}

reader.close();

}/*** 执行这个main方法进行查询之前,必须要有索引,即先执行Indexer这个类

*

*@paramargs*/

public static voidmain(String[] args) {

String indexDir= "D:\\lucene";

String q= "ADD";try{

search(indexDir, q);

}catch(Exception e) {

e.printStackTrace();

}

}

}

Java小生店铺:

手机端:搜索 java小生店铺

希望店铺的资料能帮助到你!!!

18334349f205bf4b4a65a5e30370275e.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值