lucene创建索引的几种方式(一)
什么是索引:
根据你输入的值去找,这个值就是索引
第一种创建索引的方式:
根据文件来生成索引,如后缀为.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)
package com.wp.util; import java.io.File;
import java.io.FileReader;
import java.nio.file.Paths; 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.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory; public class Indexer { private IndexWriter writer; // 写索引实例 /**
* 构造方法 实例化IndexWriter
*
* @param indexDir
* @throws Exception
*/
public Indexer(String indexDir) throws Exception {
Directory dir = FSDirectory.open(Paths.get(indexDir));// 根据路径获取存储索引的目录
Analyzer analyzer = new StandardAnalyzer(); // 这里用了多态,StandardAnalyzer是标准分词器,Analyzer是一个分词器
IndexWriterConfig iwc = new IndexWriterConfig(analyzer); writer = new IndexWriter(dir, iwc); } /** * 关闭写索引 * * @throws Exception */ public void close() throws Exception { writer.close(); } /** * 索引指定目录的所有文件 * * @param dataDir * @throws Exception */ public int index(String dataDir) throws Exception { File[] files = new File(dataDir).listFiles(); for (File f : files) { indexFile(f); } return writer.numDocs(); } /** * 索引指定文件 * * @param f */ private void indexFile(File f) throws Exception { // 关于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); } /** * 获取文档,文档里再设置每个字段 * * @param f */ private Document getDocument(File f) throws Exception { Document doc = new Document(); doc.add(new TextField("contents", new FileReader(f))); doc.add(new TextField("fileName", f.getName(), Field.Store.YES)); doc .add(new TextField("fullPath", f.getCanonicalPath(), Field.Store.YES)); return doc; } public static void main(String[] args) { String indexDir = "D:\\lucene4"; String dataDir = "D:\\lucene4\\data"; Indexer indexer = null; int numIndexed = 0; long start = System.currentTimeMillis(); try { indexer = new Indexer(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) + " 毫秒"); } }
第二种创建索引的方式:
根据字段来生成索引,我用的是数组
第一步:创建索引
第二步:将字段添加到文档中
package com.wp.util; import java.nio.file.Paths; 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.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test; public class IndexIngTest { 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
* @throws Exception
*/
private IndexWriter getWriter() throws Exception {
Analyzer analyzer = new StandardAnalyzer(); // 标准分词器
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(dir, iwc);
return writer;
} /**
* 添加文档
*
* @throws Exception
*/
@Before
public void setUp() throws Exception {
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();
} /**
* 测试写了几个文档
*
* @throws Exception
*/
@Test
public void testIndexWriter() throws Exception {
IndexWriter writer = getWriter();
System.out.println("写入了" + writer.numDocs() + "个文档");
writer.close();
} /**
* 测试读取文档
*
* @throws Exception
*/
@Test
public void testIndexReader() throws Exception {
IndexReader reader = DirectoryReader.open(dir);
System.out.println("最大文档数:" + reader.maxDoc());
System.out.println("实际文档数:" + reader.numDocs());
reader.close();
} /**
* 测试删除 在合并前
*
* @throws Exception
*/
@Test
public void testDeleteBeforeMerge() throws Exception {
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();
} /**
* 测试删除 在合并后
*
* @throws Exception
*/
@Test
public void testDeleteAfterMerge() throws Exception {
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();
} /**
* 测试更新
*
* @throws Exception
*/
@Test
public void testUpdate() throws Exception {
IndexWriter writer = getWriter();
Document doc = new Document();
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();
}
}
生成的索引文件如下:

关于索引的搜索:
这里有一个要注意的地方:一定要先创建出索引后才能去进行查找,否则会报
package com.wp.lucene; import java.nio.file.Paths; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.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; public class Searcher {
/**
*
* @param indexDir
* 哪个目录
* @param q
* 要查询的字段
* @throws Exception
*/
public static void search(String indexDir, String q) throws Exception {
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这个类
*
* @param args
*/
public static void main(String[] args) {
String indexDir = "D:\\lucene";
String q = "ADD";
try {
search(indexDir, q);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java小生店铺:
Pc端:http://shop125970977.taobao.com/index.htm
手机端:搜索 java小生店铺
希望店铺的资料能帮助到你!!!

lucene创建索引的几种方式(一)的更多相关文章
- 0036 Java学习笔记-多线程-创建线程的三种方式
创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...
- 【java并发】传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...
- js学习-DOM之动态创建元素的三种方式、插入元素、onkeydown与onkeyup两个事件整理
动态创建元素的三种方式: 第一种: Document.write(); <body> <input type="button" id="btn" ...
- 创建TabHost的两种方式的简单分析
最近做了一个TabHost的界面,在做的过程中发现了一些问题,故和大家分享一下. 首先我的界面如下: 目前就我所知,创建TabHost有两种方式,第一种是继承TabActivity类,然后用getTa ...
- Java创建线程的第二种方式:实现runable接口
/*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法 将线程要运行的代码存放在 ...
- 创建线程的两种方式比较Thread VS Runnable
1.首先来说说创建线程的两种方式 一种方式是继承Thread类,并重写run()方法 public class MyThread extends Thread{ @Override public vo ...
- lucene创建索引简单示例
利用空闲时间写了一个使用lucene创建索引简单示例, 1.使用maven创建的项目 2.需要用到的jar如下: 废话不多说,直接贴代码如下: 1.创建索引的类(HelloLucene): packa ...
- Java中创建线程的两种方式
创建线程的第一种方式: 创建一个类继承Thread 重写Thread中的run方法 (创建线程是为了执行任务 任务代码必须有存储位置,run方法就是任务代码的存储位置.) 创建子类对象,其实就是在创建 ...
- javascript创建类的6种方式
javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...
随机推荐
- javap指令
栈和局部变量操作将常量压入栈的指令aconst_null 将null对象引用压入栈iconst_m1 将int类型常量-1压入栈iconst_0 将int类型常量0压入栈iconst_1 将int类型 ...
- 学习 Spring (十六) AOP API
Spring入门篇 学习笔记 Spring AOP API 是 Spring 1.2 历史用法,现在仍然支持 这是 Spring AOP 基础,现在的用法也是基于历史的,只是更简便了 Pointcut ...
- DotNetty 实现 Modbus TCP 系列 (三) Codecs & Handler
本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 DotNetty 作为一个半成品,我们不需要关注细节的实现,只需要关注自己的业务即可,所以最主要的就是处理 Codecs ...
- python爬虫requests模块
requests库的七个主要方法 1. requests.requests(method, url, **kwargs) 构造一个请求,支撑以下各方法的基础方法 method:请求方式,对应get/p ...
- 51Nod 1381 硬币游戏
参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6445369.html 1381 硬币游戏 基准时间限制:1 秒 空间限制:131072 KB 分值 ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- PHP linux ZendGuardLoader.so: undefined symbol: executor_globals
/usr/xxx/php xxx/xxx.php 报了这个错. 本人出现此问题的原因: php执行程序路径错了. 解决: linux下执行 which php 命令 查看php真实路 ...
- 自学Zabbix4.0之路
自学Zabbix4.0之路 01 Centos7安装Zabbix4.0步骤 02 Centos7下Zabbix3.4至Zabbix4.0的升级步骤 03 Zabbix4.0添加cisco交换机基本监控 ...
- rt-thread中线程内置定时器的作用 ---
@2019-01-15 [小记] 常见到在内核组件的接口函数中,配置和启动一个定时器后,启动线程调度 我猜想是超时时间到达后恢复调用接口函数的线程以执行线程调度语句后的代码
- 部署KVM
1.安装前准备1)服务器或者PC的CPU能支持VT技术2)虚拟机中安装KVM要勾选:处理器:虚拟化Intel VT-x/EPT或AMD-V/RVI(V)[root@localhost ~]# cat ...