在学习Lucene之前呢,我们当然首先要了解下什么是Lucene.

0x01 什么是Lucene ?

Lucene是一套用于全文检索和搜索的开放源代码程序库,由Apache软件基金会支持和提供。

Lucene提供了一个简单却强大的应用程序接口,能够做全文索引和搜索,在Java开发环境里Lucene是一个成熟的免费开放源代码工具;

就其本身而论,Lucene是现在并且是这几年,最受欢迎的免费Java信息检索程序库。

Lucene最初是由Doug Cutting所撰写的,他贡献出Lucene的目标是为各种中小型应用程序加入全文检索功能

Tips: 摘要来自维基百科 https://zh.wikipedia.org/wiki/Lucene

这里我们只需要知道Lucene是目前最为流行的基于 Java 开源全文检索工具包。

0x02 Lucene 是用来做什么的?

基于Lucene的著名项目

项目名称  项目描述
Apache Nutch  提供成熟可用的网络爬虫
Apache Solr   基于Lucenne核心的高性能搜索服务器,提供JSON/Python/Ruby API
Elasticsearch   企业搜索平台,目的是组织数据并使其易于获取
DocFetcher 跨平台的本机文件搜索桌面程序
Lucene.NET  提供给.Net平台用户的Lucene类库的封装
Swiftype 基于Lucene的企业级搜索
Apache Lucy 为动态语言提供全文搜索的能力,是Lucene Java 库的C接口

其实我们不难发现主要用途

  • 可以用来编写网络爬虫
  • 也可以用来实现网站后台的全文检索。

偶然发现这张图感觉挺不错的,在这里分享下:

搜索应用程序和 Lucene 之间的关系

Lucene 能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化的文本的,Lucene 就能对你的文档进行索引和搜索。

0x03 Lucene 软件包分析

Lucene 软件包的发布形式是一个 JAR 文件,下面我们分析一下这个 JAR 文件里面的主要的 JAVA 包,使读者对之有个初步的了解。

Package: org.apache.lucene.document

这个包提供了一些为封装要索引的文档所需要的类,比如 Document, Field。这样,每一个文档最终被封装成了一个 Document 对象。

Package: org.apache.lucene.analysis

这个包主要功能是对文档进行分词,因为文档在建立索引之前必须要进行分词,所以这个包的作用可以看成是为建立索引做准备工作。

Package: org.apache.lucene.index

这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。这里面有两个基础的类:IndexWriter 和 IndexReader,

其中 IndexWriter 是用来创建索引并添加文档到索引中的,IndexReader 是用来删除索引中的文档的。

Package: org.apache.lucene.search

这个包提供了对在建立好的索引上进行搜索所需要的类。比如 IndexSearcher 和 Hits, IndexSearcher 定义了在指定的索引上进行搜索的方法,Hits 用来保存搜索得到的结果。

0x04 搭建Lucene 开发环境?

相信你和我一样已经控制不住自己的洪荒之力想要写个demo来跑跑了,但是在此之前我们还是要先搭建好开发环境。

1. 首先我们需要找到Lucene的官网

Lucene官网:https://lucene.apache.org/

翻译内容如下:

Apache LuceneTM项目开发开源搜索软件,其中包括:

我们的旗舰子项目Lucene Core提供了基于Java的索引和搜索技术,以及拼写检查,高亮显示和高级分析/标记化功能。
SolrTM是一款使用Lucene Core构建的高性能搜索服务器,具有XML / HTTP和JSON / Python / Ruby API,高亮显示,多面搜索,缓存,复制和Web管理界面。
PyLucene是Core项目的Python端口。

2.点击上图中的Download 按钮,会跳转到这个下载页面

Tips: 这里存在很多镜像下载链接,我们选择推荐的下载链接下载即可。

0x05 Lucene Hello World Sample

文档资料相信你在其他网站已经看了不少,但是不写一个能跑起来的Hello World 对于初学者来说是非常痛苦的。

对于这个简单的例子,我们将从一些字符串中创建一个内存索引

1.创建Maven 项目

2.选择创建一个简单的Maven Project

3. 配置工程信息

4. 点击完成

5. 配置POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xingyun</groupId>
<artifactId>lucene-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>lucene-sample</name> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>ex</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>HelloLucene.HelloLucene</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build> <dependencies>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</project>

6. 创建HelloLucene.java

package com.xingyun;

import java.io.IOException;
import java.text.ParseException; 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.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.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version; public class HelloLucene { public static void main(String[] args) throws IOException, ParseException { // 对于这个简单的例子,我们将从一些字符串中创建一个内存索引。
// 0. Specify the analyzer for tokenizing text.
// The same analyzer should be used for indexing and searching
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40); // 1. create the index
Directory index = new RAMDirectory(); IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer); IndexWriter w = new IndexWriter(index, config);
addDoc(w, "Lucene in Action", "193398817");
addDoc(w, "Lucene for Dummies", "55320055Z");
addDoc(w, "Managing Gigabytes", "55063554A");
addDoc(w, "The Art of Computer Science", "9900333X");
w.close(); // 2. query
String querystr = args.length > 0 ? args[0] : "lucene"; // the "title" arg specifies the default field to use
// when no field is explicitly specified in the query.
Query q = null;
try {
q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);
} catch (org.apache.lucene.queryparser.classic.ParseException e) {
e.printStackTrace();
} // 3. search
int hitsPerPage = 10;
IndexReader reader = DirectoryReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
searcher.search(q, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs; // 4. display results
System.out.println("Found " + hits.length + " hits.");
for (int i = 0; i < hits.length; ++i) {
int docId = hits[i].doc;
Document d = searcher.doc(docId);
System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));
} // reader can only be closed when there
// is no need to access the documents any more.
reader.close();
} private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {
Document doc = new Document();
doc.add(new TextField("title", title, Field.Store.YES)); // use a string field for isbn because we don't want it tokenized
doc.add(new StringField("isbn", isbn, Field.Store.YES));
w.addDocument(doc);
} }

7. 运行后,我们便可以得到索引集合中带有Lucene的所有内容

0x06  代码剖析

我们运行成功后,相信此时的你已经有心情和我一起来分析代码了吧。

1. 创建索引

StandardAnalyzer analyzer = new StandardAnalyzer();
Directory index = new RAMDirectory(); IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter w = new IndexWriter(index, config);
addDoc(w, "Lucene in Action", "193398817");
addDoc(w, "Lucene for Dummies", "55320055Z");
addDoc(w, "Managing Gigabytes", "55063554A");
addDoc(w, "The Art of Computer Science", "9900333X");
w.close();

我们需要虚构一些假的数据,通过上面的方式来对一些字符串和数字创建索引

addDoc 方法定义如下所示:

private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {
Document doc = new Document();
doc.add(new TextField("title", title, Field.Store.YES));
doc.add(new StringField("isbn", isbn, Field.Store.YES));
w.addDocument(doc);
}

2. 查询

String querystr = args.length > 0 ? args[0] : "lucene";
Query q = new QueryParser("title", analyzer).parse(querystr);

3.搜索

int hitsPerPage = 10;
IndexReader reader = DirectoryReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs docs = searcher.search(q, hitsPerPage);
ScoreDoc[] hits = docs.scoreDocs;

4.显示结果

System.out.println("Found " + hits.length + " hits.");
for(int i=0;i<hits.length;++i) {
int docId = hits[i].doc;
Document d = searcher.doc(docId);
System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));
}

0x07 参考资料:

Lucene in 5 minutes:http://www.lucenetutorial.com/lucene-in-5-minutes.html

Lucene常识总结以及小demo总结  http://www.imooc.com/article/21946

Lucene 概述: https://www.ibm.com/developerworks/cn/java/j-lo-lucene1/

视频实战教程:

基于Lucene4.6+Solr4.6+Heritrix1.14+S2SH实战开发从无到有垂直搜索引擎

网盘地址:https://pan.baidu.com/s/1nwkAamt 密码: 9ang

备用地址(腾讯微云):http://url.cn/5CmEW7s 密码:p8TmhQ

最新文章

  1. blade and soul races guide
  2. Andriod Studio adb.exe,start-server&#39; failed -- run manually if necessary 解决
  3. bootstrap-8
  4. DateGridew导出Excel表+常见错误提示
  5. Hyper-v虚拟机上网
  6. 《Programming WPF》翻译 第9章 5.默认可视化
  7. Windows 8 动手实验系列教程 实验8:Windows应用商店API
  8. 天梯赛决赛 L2-1.红色警报 并查集
  9. IIS无法启动,应用程序池自动关闭,应用程序池XXXX将被自动禁用 解决方案之一
  10. ServletContext对象统计在线人数
  11. 安全终端模拟工具Xshell 5使用密钥认证登录配置详细教程
  12. Spark性能调优之资源分配
  13. bzoj 4830: [Hnoi2017]抛硬币
  14. TS学习随笔(三)-&gt;接口
  15. AWS Add Key Pair to Elastic Beanstalk Instance 给EB实例加密钥
  16. linux内核中的hisi_sas是什么?
  17. Windows 10 中的存储空间
  18. 设计模式之迭代器模式(Iterator Pattern)
  19. [WEB面试题] web前端面试题JavaScript第一弹,个人整理部分面试题汇总
  20. Linux 系统的文件类型

热门文章

  1. svnserve.conf: Option expected的问题解决方法
  2. Django学习-8-模板渲染的一些特性
  3. spring boot + vue + element-ui全栈开发入门——基于Electron桌面应用开发
  4. 决策树系列(三)——ID3
  5. C# 扩展方法 白话总结
  6. C# wav语音文件合并
  7. 促进客户转化,提高客单价!酷客多小程序发布版本V1.0.9!
  8. 通过JDBC连接数据库(MySql为例)并读取数据库信息--JSP基础
  9. 神级程序员:让你的爬虫就像人类的用户行为! 你敢封我IP吗?
  10. 【BZOJ1969】航线规划(Link-Cut Tree)