搜索引擎系列 ---lucene简介 创建索引和搜索初步
一、什么是Lucene?
Lucene最初是由Doug Cutting开发的,2000年3月,发布第一个版本,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎 ;Lucene得名于Doug妻子的中名,同时这也她外祖母的姓;目前是Apache基金会的一个顶级项目,同时也是学习搜索引擎入门必知必会。
Lucene 是一个 JAVA 搜索类库,它本身并不是一个完整的解决方案,需要额外的开发工作。
优点:成熟的解决方案,有很多的成功案例。apache 顶级项目,正在持续快速的进步。庞大而活跃的开发社区,大量的开发人员。它只是一个类库,有足够的定制和优化空间:经过简单定制,就可以满足绝大部分常见的需求;经过优化,可以支持 10亿+ 量级的搜索。
缺点:需要额外的开发工作。所有的扩展,分布式,可靠性等都需要自己实现;非实时,从建索引到可以搜索中间有一个时间延迟,而当前的“近实时”(Lucene Near Real Time search)搜索方案的可扩展性有待进一步完善。
对于全文检索一般都由以下3个部分组成:
- 索引部分
- 分词部分
- 搜索部分
在接下来的一系列文章中会详细介绍这三个部分,本文将简单介绍lucene环境搭建以及lucene索引初步。
目前基于Lucene的产品有:
Solr,Nutch,Hbase,Katta,constellio,Summa,Compass,Bobo Search,Index Tank,Elastic Search,Hadoop contrib/index ,LinkedIn ,Eclipse,Cocoon
二、Lucene环境搭建
目录最新版的Lucene为4.10.0(今天是2014-09-22 )版,其官方主页为:http://lucene.apache.org/
或者点击下载
如果你会使用Maven,那么可以非常简单的将pom.xml中加入以下内容即可:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.0</version>
</dependency>
如果不会使用Maven,则需要手工下载相应的jar包进行开发。
三、索引创建
1、创建Directory
2、创建IndexWriter
3、创建Document对象
4、为Docuemnt添加Field
5、通过IndexWriter添加文档到Document
package com.amos.lucene; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.IndexableFieldType;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version; import java.io.File;
import java.io.FileReader;
import java.io.IOException; /**
* Created by amosli on 14-9-17.
*/
public class HelloLucene {
static String indexDir = "/home/amosli/developtest/lucene"; public void index() {
IndexWriter indexWriter = null;
FSDirectory directory = null;
try {
//1、创建Directory
directory = FSDirectory.open(new File(indexDir));
//RAMDirectory directory = new RAMDirectory(); //2、创建IndexWriter
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_0, new StandardAnalyzer(Version.LUCENE_4_10_0));
indexWriter = new IndexWriter(directory, indexWriterConfig); File file = new File("/home/amosli/developtest/testfile");
for (File f : file.listFiles()) { FieldType fieldType = new FieldType();
//3、创建Docuemnt对象
Document document = new Document(); //4、为Document添加Field
document.add(new TextField("content", new FileReader(f)) ); fieldType.setIndexed(true);
fieldType.setStored(true);
document.add(new Field("name", f.getName(),fieldType)); fieldType.setIndexed(false);
fieldType.setStored(true);
document.add(new Field("path", f.getAbsolutePath(), fieldType)); //5、通过IndexWriter添加文档索引中
indexWriter.addDocument(document); }
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close(); } catch (IOException e) {
e.printStackTrace();
}
}
}
} }
注:
1、这里使用的是FSDirectory,是为了方便进行测试,将生成的文件写入到本地硬盘中;
2、Document相当于数据库中的一条记录,field相当数据库中表的一列;
3、使用indexWriter当记录添加到文档索引中;
4、fieldType可以设置是否需要索引和是否需要存储;
5、记得关闭indexWriter
生成的索引文件,如下图所示:

四、搜索记录
1、创建Directory
2、创建IndexReader
3、根据IndexReader创建IndexSearcher
4、创建搜索的Query
5、根据Searcher搜索并且返回TopDocs
6、根据TopDocs获取ScoreDoc对象
7、根据Seacher和ScoreDoc对象获取具体的Document对象
8、根据Document对象获取需要的值
public void search() {
IndexReader indexReader = null;
try {
//1、创建Directory
FSDirectory directory = FSDirectory.open(new File(indexDir));
//2、创建IndexReader
indexReader = DirectoryReader.open(directory);
//3、根据IndexReader创建IndexSearcher
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//4、创建搜索的Query
//创建querypaser来确定要搜索文件的内容,第二个参数表示搜索的域
QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());
//创建query,表示搜索域为content中包含java的文档
Query query = queryParser.parse("java");
//5、根据Searcher搜索并且返回TopDocs
TopDocs topDocs = indexSearcher.search(query, 100);
//6、根据TopDocs获取ScoreDoc对象
ScoreDoc[] sds = topDocs.scoreDocs;
//7、根据Seacher和ScoreDoc对象获取具体的Document对象
for (ScoreDoc sdc : sds) {
Document doc = indexSearcher.doc(sdc.doc);
//8、根据Document对象获取需要的值
System.out.println("name:" + doc.get("name") + "-----> path:" + doc.get("path"));
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}finally{
if(indexReader!=null){
try {
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:

所有源码:HelloLucene.java
package com.amos.lucene; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
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.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version; import java.io.File;
import java.io.FileReader;
import java.io.IOException; /**
* Created by amosli on 14-9-17.
*/
public class HelloLucene {
static String indexDir = "/home/amosli/developtest/lucene"; public void index() {
IndexWriter indexWriter = null;
FSDirectory directory = null;
try {
//1、创建Directory
directory = FSDirectory.open(new File(indexDir));
//RAMDirectory directory = new RAMDirectory(); //2、创建IndexWriter
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_0, new StandardAnalyzer(Version.LUCENE_4_10_0));
indexWriter = new IndexWriter(directory, indexWriterConfig); File file = new File("/home/amosli/developtest/testfile");
for (File f : file.listFiles()) { FieldType fieldType = new FieldType();
//3、创建Docuemnt对象
Document document = new Document(); //4、为Document添加Field
document.add(new TextField("content", new FileReader(f))); fieldType.setIndexed(true);
fieldType.setStored(true);
document.add(new Field("name", f.getName(), fieldType)); fieldType.setIndexed(false);
fieldType.setStored(true);
document.add(new Field("path", f.getAbsolutePath(), fieldType)); //5、通过IndexWriter添加文档索引中
indexWriter.addDocument(document); }
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close(); } catch (IOException e) {
e.printStackTrace();
}
}
}
} public void search() {
IndexReader indexReader = null;
try {
//1、创建Directory
FSDirectory directory = FSDirectory.open(new File(indexDir)); //2、创建IndexReader
indexReader = DirectoryReader.open(directory); //3、根据IndexReader创建IndexSearcher
IndexSearcher indexSearcher = new IndexSearcher(indexReader); //4、创建搜索的Query
//创建querypaser来确定要搜索文件的内容,第二个参数表示搜索的域
QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());
//创建query,表示搜索域为content中包含java的文档
Query query = queryParser.parse("java");
//5、根据Searcher搜索并且返回TopDocs
TopDocs topDocs = indexSearcher.search(query, 100);
//6、根据TopDocs获取ScoreDoc对象
ScoreDoc[] sds = topDocs.scoreDocs;
//7、根据Seacher和ScoreDoc对象获取具体的Document对象
for (ScoreDoc sdc : sds) {
Document doc = indexSearcher.doc(sdc.doc);
//8、根据Document对象获取需要的值
System.out.println("name:" + doc.get("name") + "-----> path:" + doc.get("path"));
} } catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}finally{ if(indexReader!=null){
try {
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }
TestHelloLucene.java
package com.amos.lucene; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.junit.Test; /**
* Created by amosli on 14-9-17.
*/
public class TestHelloLucene {
@Test
public void testIndex(){
HelloLucene helloLucene = new HelloLucene();
helloLucene.index();
}
@Test
public void testSearch(){
HelloLucene helloLucene = new HelloLucene();
helloLucene.search();
}
}
搜索引擎系列 ---lucene简介 创建索引和搜索初步的更多相关文章
- lucene简介 创建索引和搜索初步
lucene简介 创建索引和搜索初步 一.什么是Lucene? Lucene最初是由Doug Cutting开发的,2000年3月,发布第一个版本,是一个全文检索引擎的架构,提供了完整的查询引擎和索引 ...
- Lucene底层原理和优化经验分享(1)-Lucene简介和索引原理
Lucene底层原理和优化经验分享(1)-Lucene简介和索引原理 2017年01月04日 08:52:12 阅读数:18366 基于Lucene检索引擎我们开发了自己的全文检索系统,承担起后台PB ...
- Lucene.net 从创建索引到搜索的代码范例
关于Lucene.Net的介绍网上已经很多了在这里就不多介绍Lucene.Net主要分为建立索引,维护索引和搜索索引Field.Store的作用是通过全文检查就能返回对应的内容,而不必再通过id去DB ...
- 《Lucene in Action》(第二版) 第一章节的学习总结 ---- 用最少的代码创建索引和搜索
第一章节是介绍性质,但是通过这一章节的学习,我理解到如下概念: 1.Lucene由两部分组成:索引和搜索.索引是通过对原始数据的解析,形成索引的过程:而搜索则是针对用户输入的查找要求,从索引中找到匹配 ...
- lucene学习-创建索引
本文的lucene是基于lucene3.5版本. 使用lucene实现搜索引擎开发,核心的部分是建立索引和搜索.本节主要是记录创建索引部分的内容. 创建的索引结构如图所示. 创建索引的步骤分为以下几个 ...
- Lucene第二讲——索引与搜索
一.Feild域 1.Field域的属性 是否分词:Tokenized 是:对该field存储的内容进行分词,分词的目的,就是为了索引. 否:不需要对field存储的内容进行分词,不分词,不代表不索引 ...
- (一)Lucene简介以及索引demo
一.百度百科 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查 ...
- lucene中创建索引库
package com.hope.lucene;import org.apache.commons.io.FileUtils;import org.apache.lucene.document.Doc ...
- lucene入门创建索引——(二)
1.程序宏观结构图
随机推荐
- python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库).自定义Field.数据表更改.QuerySet API 一.Django 模型(数据库) Django 模型是与数据库相关的,与数据库相关的代码 ...
- zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法
转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...
- jquery中的ajax参数
jquery中将ajax封装成了函数,我们使用起来非常方便,jquery会自动根据内容选择post还是get方式提交数据,并且会自动编码,但是要想完全掌握jquery中的ajax,我们必须将它的各个参 ...
- MySQL 5.7 Command Line Client输入密码后闪退和windows下mysql忘记root密码的解决办法
MySQL 5.7 Command Line Client输入密码后闪退的问题: 问题分析: 1.查看mysql command line client默认执行的一些参数.方法:开始->所有程序 ...
- jsp中两种include的区别【转】
引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...
- mysql日志开启和查看
mysql日志开启和查看. 找到mysql根目录下的my.ini文件,打开在下面插入 log-bin=mysql-bin binlog_format=mixed 然后重启mysql. 在dos端登录m ...
- windows下多字节和宽字节转换
先简单说下什么是多字节和宽字节. 多字节是指使用多个字节(1-3)表示一个字符.比如gbk使用英文占一个字节,中文占2个,这个就是多字节了.utf-8是使用1-3个字节表示字符.还有big5等等. 宽 ...
- 动态设置和访问cxgrid列的Properties(转)
原文:http://www.cnblogs.com/hnxxcxg/archive/2010/05/24/2940711.html 动态设置和访问cxgrid列的Properties 设置: cxGr ...
- findViewById返回null
Q:findViewById返回null? A: 代码逻辑错误: 最终,发现错误竟然是在layout文件中把android:id写成了android:name. android:name=" ...
- shell生成随机数的几种方法
一.通过内部系统变量($RANDOM) 生成0-32767之间的整数随机数,若超过5位可以加个固定10位整数,然后进行求余. [root@web01 scripts]# echo $RANDOM [r ...