在了解了Lucene以后,我打算亲手来做一个Lucene的小例子,这个例子只是Lucene最简单的应用:使用Lucene实现标准的英文搜索;

1、下载Lucene

下载Lucene,到Lucene的官方下载http://lucene.apache.org/;

2、新建项目

新建一个Java Project 然后引入Lucene的jar 包:

因为要实现的功能非常简单,所以Jar包只引入了一部分,当然Lucene的jar包远远不止这些;

core包:Lucene的核心包

analyzers包:主要进行对采集的内容和用户输入的内容进行分词;

highlighter包:主要对搜索的结果进行高亮显示,就像百度搜索结果标红一样;

queries和queryparser包:搜索查询包,根据用户输入关键定去检索内容;

主要用到这三个包;

3、准备数据源文件

要让用户搜索结果,首先得有数据源, 我准备了几个文本文档,里面全是英文内容:

将这些文本文件放在一个全英文的目录里面,同时还要建一些纯英文的目录用来存放索引文件;

4、对数据源进行索引

在用户进行搜索前,系统得先对数据源进行分析,排序,分词,创建索引;这是一步很关键的工作:

新建一个CreateIndex类,代码如下:

package com.lucene;
import java.io.File;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.util.CharArraySet;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test; public class CreateIndex {
/** 数据源目录 **/
public static final String DATA_DIR="E:/data/lucene/en/data";
/** 索引目录 **/
public static final String INDEX_DIR="E:/data/lucene/en/index";
@Test
public void create(){
try {
Directory dir = FSDirectory.open(new File(INDEX_DIR));
//4. 通过CharArraySet可以向分词中追加一些停止词(即排除检索的词)
CharArraySet arrSet = new CharArraySet(Version.LUCENE_4_9, 0, false);
//3. Analyzer 用于对数据源进行分词
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9, arrSet);
//2. IndexWriter的配置信息都存放在IndexWriterConfig中
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9,analyzer);
// OpenMode.CREATE_OR_APPEND 指定,该创建索引是可以在以后通过追加的方式向里面添加内容
config.setOpenMode(OpenMode.CREATE_OR_APPEND);
//1. 创建索引的入口,创建索引必须用IndexWriter进行创建或者追加
IndexWriter writer = new IndexWriter(dir,config);
File dataDir = new File(DATA_DIR);
//5.得到数据源中所有的文件
Collection<File> files = FileUtils.listFiles(dataDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
for(File file : files){
//6. 通过向Writer追加Document的方式添加内容
Document doc = new Document();
doc.add(new StringField("filename",file.getName(), Store.YES));
String content = FileUtils.readFileToString(file);
doc.add(new TextField("content",content,Store.YES));
writer.addDocument(doc);
}
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

在新建完CreateIndex类以后,可以使用Test运行一下,然后在索引目录就会生成一些这样的文件:

这就是Lucene创建完索引的索引数据库了;

5、创建检索

创建一个SearchIndex类,主要作用是通过用户输入内容分词,然后检索出用户想要的结果:

import java.io.File;
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;
import org.apache.lucene.util.Version;
import org.junit.Test; public class SearchIndex {
@Test
public void search(){
try {
String keyword = "java";
// 在这里进行检索的时候,需要加载的目录就是创建索引的目录,创建索引以后,那些原数据源在Lucene上就暂时用不到了
Directory directory = FSDirectory.open(new File(CreateIndex.INDEX_DIR));
IndexReader reader = DirectoryReader.open(directory);
// IndexSearcher 是Lucene的检索的入口点,所有检索都从这里入口
IndexSearcher searcher = new IndexSearcher(reader);
// 通过analyzer对用户输入的词进行分词
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9);
// 构建检索条件
QueryParser parser = new QueryParser(Version.LUCENE_4_9, "content",analyzer);
Query query = parser.parse(keyword);
// 最后使用searcher.search检索,search方法的参数很多,还可以根据需求,取出相应的条数
TopDocs topDocs = searcher.search(query, 20);
// topDocs.totalHits 返回的是所有检索到记录的条数的总和
ScoreDoc[] docs = topDocs.scoreDocs;
System.out.println("关键词\" "+keyword+" \"共检索到 "+topDocs.totalHits+" 条相关的记录");
System.out.println("被检索到记录,他们分别放在以下的文件中:");
for(ScoreDoc doc : docs){
int docId = doc.doc;
Document document = reader.document(docId);
System.out.println(document.get("filename"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

为了方便,我摸拟了一个搜索词“java” 看能查询出多少条数据,运行单元测试:

小结:这只是Lucene的最简单的用法,还有很多高深的用法,可以查看Lucene的官方文档,Lucene用来检索中文同样很厉害,大家快去试试吧;下小节我会贴出我写的使用Lucene来做一个千度搜索;

2、Lucene 最简单的使用(小例子)的更多相关文章

  1. 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子

    原地址:http://www.cnblogs.com/xuling/archive/2013/03/04/2943154.html 最近开始研究U3D,它的强大就不多说了, 今天研究了研究射线相关东西 ...

  2. Android ExpandableListActivity的简单介绍及小例子

    Android中常常要用到ListView,但也经常要用到ExpandableListView,ListView是显示列表,而ExpandableListView显示的是分类的列表: 下面用一个例子来 ...

  3. C#网络编程简单实现通信小例子-1

    1.主界面 2.源程序 Send public partial class formUdpSend : Form { //声明一个UdpClient对象 UdpClient udpClient; pu ...

  4. C#网络编程简单实现通信小例子-2

    1.主界面  2.源代码                                                         Client public partial class For ...

  5. spring小例子-springMVC+mybits整合的小例子

    这段时间没更博,找房去了...   吐槽一下,自如太坑了...承诺的三年不涨房租,结果今年一看北京房租都在涨也跟着涨了... 而且自如太贵了,租不起了.. 突然有点理解女生找对象要房了..   搬家太 ...

  6. python2.7练习小例子(十)

        10):古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?     程序分析:兔子的规律为数列1,1 ...

  7. ASP.NET Cookie对象到底是毛啊?(简单小例子)

    记得刚接触asp.net的时候,就被几个概念搞的头痛不已,比如Request,Response,Session和Cookie.然后还各种在搜索引擎搜,各种问同事的,但是结果就是自己还是很懵的节奏. 那 ...

  8. lucene.net 3.0.3、结合盘古分词进行搜索的小例子(转)

    lucene.net 3.0.3.结合盘古分词进行搜索的小例子(分页功能)   添加:2013-12-25 更新:2013-12-26 新增分页功能. 更新:2013-12-27 新增按分类查询功能, ...

  9. php+jquery+ajax+json简单小例子

    直接贴代码: <html> <title>php+jquery+ajax+json简单小例子</title> <?php header("Conte ...

随机推荐

  1. Linux系统编程(19)——正则表达式在sed和awk中的使用

    sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换为另一种格式输出.sed和 ...

  2. JOB+MERGE 跨服务器同步数据

    为了解决单服务器压力,将库分服务器部署,但是原来用触发器实现的表数据同步就实现不了了. 因为总监老大不允许 开启分布式事务(MSDTC),我又不想为了一个几千行的基础数据做复制订阅. 于是乎决定用 J ...

  3. GridBagLayout练习

    摘自http://blog.csdn.net/qq_18989901/article/details/52403737  GridBagLayout的用法 GridBagLayout是面板设计中最复杂 ...

  4. webpack+gulp实现自动构建部署

    项目结构说明 . ├── gulpfile.js # gulp任务配置 ├── mock/ # 假数据文件 ├── package.json # 项目配置 ├── README.md # 项目说明 ├ ...

  5. RMAN数据库恢复之丢失数据文件的恢复

    删除某一数据文件:SQL> HOST del D:\app\Administrator\oradata\orcl\USERS01.dbf 启动数据库,提示丢失数据文件4,此时数据库处理MOUNT ...

  6. Ffplay视频播放流程

    主框架流程 下图是一个使用“gcc+eygpt+graphviz+手工调整”生成的一个ffplay函数基本调用关系图,其中只保留了视频部分,去除了音频处理.字幕处理以及一些细节处理部分. 注:图中的数 ...

  7. 天坑 之 Eclipse J2EE Preview 运行正确项目一直显示http 404

    昨天下载了几个新Demo学习,结果不知道改了哪里,导致运行原先自己写的项目(JSP+Servlet+JDBC)(这理论上不会出什么大的问题吧?这么底层),结果莫名其妙的出现Http 404. 搞的我一 ...

  8. Uva 10652 Board Wrapping(计算几何之凸包+点旋转)

    题目大意:给出平面上许多矩形的中心点和倾斜角度,计算这些矩形面积占这个矩形点形成的最大凸包的面积比. 算法:GRAHAM,ANDREW. 题目非常的简单,就是裸的凸包 + 点旋转.这题自己不会的地方就 ...

  9. 认识Java里面的Thread

    在一个特定的主线程执行的过程中,如果我们还需要在主线程的过程中插播一个线程,做其他动作.那么我们就可以利用Java的Thread类,创建一个新的线程. 一:线程简单实现的三种方式 (1)第一种创建线程 ...

  10. input添加邮箱的时候自动显示后缀

    1.HTML代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...