Lucene简介

Lucent:Apache软件基金会Jakarta项目组的一个子项目,Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。 —— [ 百度百科 ]

数据库索引和Lucene检索对比

比较项 Lucene检索 数据库检索
数据检索 从Lucene的索引文件中检出 由数据库索引检索记录
索引结构 Document(文档) Record(记录)
全文检索 支持 不支持
模糊查询 支持 不支持
结果排序 支持排序 不能排序

Lucene搜索的API类主要有4个 IndexSearch,Query,QueryParser,Hits

Lucene搜索过程

Lucene的索引结构是文档(Document)形式的,下面简单介绍一下Lucene搜索的过程

(1)将文档传给分词组件(Tokenizer),分词组件根据标点符号和停词将文档分成词元(Token),并将标点符号和停词去掉。

停词是指没有特别意思的词。英语的是指比如a、the等等单词

文章1内容:Tom favorite fruit is apple.

经过分词处理后,变成[Tom][facorite][fruit][apple]

(2)再将词元传给语言处理组件(Linguistic Processor)

英语的单词经过语言处理组件处理后,字母变为小写,词元会变成最基本的词根形式,比如likes变成like

经过分词处理后,变成[tom][favorite][fruit][apple]

(3) 然后得到的词元传给索引组件(Indexer),索引组件处理得到索引结构,得到关键字、出现频率、出现位置分别作为词典文件(Term Dictionary)、频率文件(frequencies)和位置文件(positions)保存起来,然后通过二元搜索算法快速查找关键字

关键字 文章号[出现频率] 出现位置
tom 1[1] 1
favorite 1[2] 2
fruit 1[3] 3
[apple 1[4] 4

Lucene简单实例

创建一个Maven项目,在pom.xml加入Lucene所需的jar

<dependencies>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>

创建索引的简单实例

package com.demo.lucene;

import java.io.IOException;
import java.nio.file.Paths; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; /**
* <pre>
* Lucene创建索引服务类
* </pre>
*
* @author nicky
* @version 1.00.00
*
* <pre>
* 修改记录
* 修改后版本: 修改人: 修改日期:2018年04月18日 修改内容:
* </pre>
*/
@Component
public class LuceneIndexer { private volatile static LuceneIndexer instance; private final static String INDEX_DIR = "D:\\lucene"; private static class SingletonHolder{
private final static LuceneIndexer instance=new LuceneIndexer();
} public static LuceneIndexer getInstance(){
return SingletonHolder.instance;
} public boolean createIndex(String indexDir) throws IOException{
//加点测试的静态数据
Integer ids[] = {1 , 2 , 3};
String titles[] = {"标题1" , "标题2" , "标题3"};
String tcontents[] = {
"内容1内容啊哈哈哈",
"内容2内容啊哈哈哈",
"内容3内容啊哈哈哈"
}; long startTime = System.currentTimeMillis();//记录索引开始时间 Analyzer analyzer = new SmartChineseAnalyzer();
Directory directory = FSDirectory.open(Paths.get(indexDir));
IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter indexWriter = new IndexWriter(directory, config); for(int i = 0; i < ids.length;i++){
Document doc = new Document();
//添加字段
doc.add(new IntField("id", ids[i],Field.Store.YES)); //添加内容
doc.add(new TextField("title", titles[i], Field.Store.YES)); //添加文件名,并把这个字段存到索引文件里
doc.add(new TextField("tcontent", tcontents[i], Field.Store.YES)); //添加文件路径
indexWriter.addDocument(doc);
} indexWriter.commit();
System.out.println("共索引了"+indexWriter.numDocs()+"个文件");
indexWriter.close();
System.out.println("创建索引所用时间:"+(System.currentTimeMillis()-startTime)+"毫秒"); return true;
} public static void main(String[] args) {
try {
boolean r = LuceneIndexer.getInstance().createIndex(INDEX_DIR);
if(r){
System.out.println("索引创建成功!");
}else{
System.out.println("索引创建失败!");
}
} catch (IOException e) {
e.printStackTrace();
} } }

全局搜索索引

package com.demo.lucene;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
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.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory; import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Paths; /**
* <pre>
* Lucene全局搜索服务类
* </pre>
*
* @author nicky
* @version 1.00.00
*
* <pre>
* 修改记录
* 修改后版本: 修改人: 修改日期:2018年04月18日 修改内容:
* </pre>
*/
public class SearchBuilder { public static void doSearch(String indexDir , String queryStr) throws IOException, ParseException, InvalidTokenOffsetsException {
Directory directory = FSDirectory.open(Paths.get(indexDir));
DirectoryReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new SmartChineseAnalyzer();
QueryParser parser = new QueryParser("tcontent",analyzer);
Query query = parser.parse(queryStr); long startTime = System.currentTimeMillis();
TopDocs docs = searcher.search(query,10); System.out.println("查找"+queryStr+"所用时间:"+(System.currentTimeMillis()-startTime));
System.out.println("查询到"+docs.totalHits+"条记录"); //遍历查询结果
for(ScoreDoc scoreDoc : docs.scoreDocs){
Document doc = searcher.doc(scoreDoc.doc);
String tcontent = doc.get("tcontent");
if(tcontent != null){
TokenStream tokenStream = analyzer.tokenStream("tcontent", new StringReader(tcontent));
String summary = highlighter.getBestFragment(tokenStream, tcontent);
System.out.println(summary);
}
}
reader.close();
} public static void main(String[] args){
String indexDir = "D:\\lucene";
String q = "内容"; //查询这个字符串
try {
doSearch(indexDir, q);
} catch (Exception e) {
e.printStackTrace();
}
}
}

加入高亮显示:

public class SearchBuilder {

    public static void doSearch(String indexDir , String queryStr) throws IOException, ParseException, InvalidTokenOffsetsException {
Directory directory = FSDirectory.open(Paths.get(indexDir));
DirectoryReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new SmartChineseAnalyzer();
QueryParser parser = new QueryParser("tcontent",analyzer);
Query query = parser.parse(queryStr); long startTime = System.currentTimeMillis();
TopDocs docs = searcher.search(query,10); System.out.println("查找"+queryStr+"所用时间:"+(System.currentTimeMillis()-startTime));
System.out.println("查询到"+docs.totalHits+"条记录"); //加入高亮显示的
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color=red>","</font></b>");
QueryScorer scorer = new QueryScorer(query);//计算查询结果最高的得分
Fragmenter fragmenter = new SimpleSpanFragmenter(scorer);//根据得分算出一个片段
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,scorer);
highlighter.setTextFragmenter(fragmenter);//设置显示高亮的片段 //遍历查询结果
for(ScoreDoc scoreDoc : docs.scoreDocs){
Document doc = searcher.doc(scoreDoc.doc);
String tcontent = doc.get("tcontent");
if(tcontent != null){
TokenStream tokenStream = analyzer.tokenStream("tcontent", new StringReader(tcontent));
String summary = highlighter.getBestFragment(tokenStream, tcontent);
System.out.println(summary);
}
}
reader.close();
} public static void main(String[] args){
String indexDir = "D:\\lucene";
String q = "内容"; //查询这个字符串
try {
doSearch(indexDir, q);
} catch (Exception e) {
e.printStackTrace();
}
}
}

查找内容1所用时间:404

查询到3条记录

内容1内容啊哈哈哈

内容2内容啊哈哈哈

内容3内容啊哈哈哈

Lucene重要类解释

IndexWriter:lucene 中最重要的的类之一,它主要是用来将文档加入索引,同时控制索引过程中的一些参数使用。



Analyzer:分析器,主要用于分析搜索引擎遇到的各种文本。常用的有

StandardAnalyzer

分析器,StopAnalyzer 分析器,WhitespaceAnalyzer 分析器等。



Directory:索引存放的位置;lucene 提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene 提供了FSDirectory 和RAMDirectory 两个类。



Document:文档;Document 相当于一个要进行索引的单元,任何可以想要被索引的文件都

必须转化为Document 对象才能进行索引。



Field:字段。



IndexSearcher:是lucene 中最基本的检索工具,所有的检索都会用到IndexSearcher工具;



Query:查询,lucene 中支持模糊查询,语义查询,短语查询,组合查询等等,如有

TermQuery,BooleanQuery,RangeQuery,WildcardQuery 等一些类。



QueryParser:是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。



Hits:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。在lucene 中,搜索的结果的集合是用Hits 类的实例来表示的。

附录

Lucene个版本下载url

Lucene易百教程

Lucene4.x系列教程

Lucene全文搜索教程

Apache Lucene全局搜索引擎入门教程的更多相关文章

  1. Flask+elasticsearch实现搜索引擎入门教程+Curl调试

    前几天,在github上看到了一个关于elasticsearch的小项目,有点小兴趣,于是就结合着Flask,研究了一下,分享给大家. 准备资料: 1.安装elasticsearch 参考教程:htt ...

  2. Apache CXF实现WebService入门教程(附完整源码)

    Apache CXF实现WebService非常简单实用,只需要几步就可以实现一个简单的web service. 首先我们需要新建一个maven项目,在pom中添加依赖和jetty作为测试的web s ...

  3. Apache Flink 零基础入门(转)

    这是一份很好的 Apache Flink 零基础入门教程. Apache Flink 零基础入门(一&二):基础概念解析 Apache Flink 零基础入门(三):开发环境搭建和应用的配置. ...

  4. Lucene入门教程(转载)

    http://blog.csdn.net/tianlincao/article/details/6867127 Lucene教程 1 lucene简介 1.1 什么是lucene     Lucene ...

  5. Apache Solr入门教程(初学者之旅)

    Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各方面,建议边思考边实践,相信能帮助你对solr有个清晰全面的了解并能简单实用. 在Apache Solr初学者教程的这个 ...

  6. Lucene搜索引擎入门

    一.什么是全文检索?            就是在检索数据,数据的分类:                在计算机当中,比如说存在磁盘的文本文档,HTML页面,Word文档等等......       ...

  7. Apache搭建http网站服务器入门教程

    Apache搭建http网站服务器入门教程 准备工具 一台带有Linux系统的主机,这里使用CentOS 7.1 64位系统 一个备案过的域名,这里使用www.hellopage.cn 一台可以访问网 ...

  8. Apache Lucene 4.5 发布,Java 搜索引擎

    Apache Lucene 4.5 发布了,该版本提供基于磁盘的文档值以及改进了过滤器的缓存.Lucene 4.5 的文档请看这里. Lucene 是apache软件基金会一个开放源代码的全文检索引擎 ...

  9. Apache Commons IO入门教程(转)

    Apache Commons IO是Apache基金会创建并维护的Java函数库.它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的 ...

随机推荐

  1. 设计模式学习心得<代理模式 Proxy>

    在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 概述 意图 为其他对象提供 ...

  2. 服务管理之samba

    目录 samba 1.samba的简介 2. samba访问 1.搭建用户认证共享服务器 2.搭建匿名用户共享服务器 samba 1.samba的简介 Samba是在Linux和UNIX系统上实现SM ...

  3. dubbo入门学习 四 注册中心 zookeeper入门

    一.Dubbo支持的注册中心 1. Zookeeper 1.1 优点:支持网络集群 1.2 缺点:稳定性受限于Zookeeper 2. Redis 2.1 优点:性能高. 2.2 缺点:对服务器环境要 ...

  4. 聚类K-Means

    import numpy as np x=np.random.randint(0,52,52) x k=3 y=np.zeros(20) y array([ 0., 0., 0., 0., 0., 0 ...

  5. 解决Xcode8模拟器无法删除应用的问题

    关闭模拟器的​3DTouch.Hardware​ →Touch Pressure→Use Trackpad Force.

  6. ubuntu18.04搭建nfs

    1.服务端安装 #apt-get update -y #apt-get install -y nfs-kernel-server #apt-get enable nfs-kernel-server 2 ...

  7. Codeforces 845 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然 ...

  8. Codeforces 837 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 并没有找到难度评级但感觉是div3div3div3场. A题 题意:一个单词的价值是里面大写字母的个数,一篇文章的价值是里面所有单词的价值的 ...

  9. JavaScript基础视频教程总结(121-130章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  10. DAO和service的解释

    转自:http://blog.sina.com.cn/s/blog_4b1452dd0102wvox.html 我们都知道有了Hibernate后,单独对数据的POJO封装以及XML文件要耗损掉一个类 ...