1. 初识 Lucene

在学习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接口

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

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

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

1. 初识 Lucene

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

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

1. 初识 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/

1. 初识 Lucene

翻译内容如下:

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

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

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

1. 初识 Lucene

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

0x05 Lucene Hello World Sample

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

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

1.创建Maven 项目

1. 初识 Lucene

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

1. 初识 Lucene

3. 配置工程信息

1. 初识 Lucene

4. 点击完成

1. 初识 Lucene

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的所有内容

1. 初识 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

上一篇:【Leetcode】【Easy】Minimum Depth of Binary Tree


下一篇:CRT注册工具使用说明