文档章节

Lucene In Action 读书笔记(一)

 林俊龙
发布于 2013/09/04 00:42
字数 1625
阅读 486
收藏 10

简介image

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。(摘自百度百科)

代码环境

操作系统:centos 5.8

开发环境:Eclipse 4.3

构建工具:Maven 4.0

Maven配置

为了能够按照书中的例子进行学习,这里依赖的Lucene版本是3.0.1

<dependencies>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>3.0.1</version>
        </dependency>
    </dependencies>

完整配置

<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.linjl.study.book</groupId>
    <artifactId>book_luceneInAction</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source />
                    <target />
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>3.0.1</version>
        </dependency>
    </dependencies>
</project>

程序示例

下面将用两个例子进行Lucene入门讲解

案例一:建立索引

案例一主要展示通过对指定路径下.txt文件建立索引的过程

完整源码:

package com.linjl.study.book.luceneInAction.chapter1;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {
    private IndexWriter indexWriter;

    public Indexer(String indexDir) throws IOException {
        //步骤一:创建 Directory
        Directory dir = FSDirectory.open(new File(indexDir));
        //步骤二:创建 IndexWriter
        indexWriter = new IndexWriter(dir, new StandardAnalyzer(
                Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);
    }

    public void close() throws CorruptIndexException, IOException {
        //步骤五:关闭IndexWriter
        indexWriter.close();
    }

    public int index(String dataDir, FileFilter fileFilter) throws IOException {
        File[] files = new File(dataDir).listFiles();
        for (File file : files) {
            if (!file.isDirectory() && !file.isHidden() && file.exists()
                    && file.canRead()
                    && (fileFilter == null || fileFilter.accept(file))) {
                indexFile(file);
            }
        }
        return indexWriter.numDocs();
    }

    private void indexFile(File file) throws IOException {
        System.out.println("Indexing " + file.getCanonicalPath());
        //步骤三:创建Document对象
        Document doc = getDocument(file);
        //步骤四:添加Document
        indexWriter.addDocument(doc);
    }

    protected Document getDocument(File file) throws IOException {
        Document doc = new Document();
        doc.add(new Field("contents", new FileReader(file)));
        doc.add(new Field("filename", file.getName(), Field.Store.YES,
                Field.Index.NOT_ANALYZED));
        doc.add(new Field("fullpath", file.getCanonicalPath(), Field.Store.YES,
                Field.Index.NOT_ANALYZED));
        return doc;
    }

    private static class TextFilesFilter implements FileFilter {

        public boolean accept(File pathname) {
            return pathname.getName().toLowerCase().endsWith(".txt");
        }

    }

    public static void main(String[] strs) throws IOException {
        //存放索引的位置(linux环境下路径)
        String indexDir = "/opt/test/lucene/index";
        //存放待索引文件的位置(linux环境下路径)
        String dataDir = "/opt/test/lucene/files";
        long startTime = System.currentTimeMillis();
        Indexer indexer = new Indexer(indexDir);
        int numIndexed;
        try {
            numIndexed = indexer.index(dataDir, new TextFilesFilter());
        } finally {
            indexer.close();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Indexing " + numIndexed + " files took "
                + (endTime - startTime) + "ms");
    }
}
案例二:搜索索引

案例二展示如何通过对指定的索引文件夹进行关键词索引

完整源码:

package com.linjl.study.book.luceneInAction.chapter1;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.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;

public class Searcher {

    public static void search(String indexDir, String searchWord)
            throws IOException, ParseException {
        //步骤一:创建Directory
        Directory dir = FSDirectory.open(new File(indexDir));
        //步骤二:创建IndexSearcher
        IndexSearcher indexSearcher = new IndexSearcher(dir);
        //步骤三:创建QueryParser
        QueryParser parser = new QueryParser(Version.LUCENE_30, "contents",
                new StandardAnalyzer(Version.LUCENE_30));
        long startTime = System.currentTimeMillis();
        //步骤四:解析生成查询对象
        Query query = parser.parse(searchWord);
        //步骤五:查询并获取查询结果(只是获取到查询结果的引用)
        TopDocs hits = indexSearcher.search(query, 30);
        long endTime = System.currentTimeMillis();
        System.out.println("Found " + hits.totalHits + "document(s) (in "
                + (endTime - startTime) + "ms) that matched query '"
                + searchWord + "':");
        for (ScoreDoc scoreDoc : hits.scoreDocs) {
            //步骤六:根据引用生成查询结果
            Document doc = indexSearcher.doc(scoreDoc.doc);
            System.out.println(doc.get("fullpath"));
        }
        //步骤七:关闭IndexSearcher
        indexSearcher.close();
    }

    public static void main(String[] args) throws IOException, ParseException {
        String indexDir = "/opt/test/lucene/index";
        String searchWord = "床";
        Searcher.search(indexDir, searchWord);
    }

理解建立索引过程的核心类

  • IndexWriter
    IndexWriter(写索引)是索引过程的核心组件。这个类负责创建新索引或者打开已有索引,以及向索引添加、删除或者更新文档的信息。他只能写入索引不能读取或者搜索索引。
  • Directory
    Directory描述了Lucene索引存放的位置。它是一个抽象类,有很多子类,例子中的FsDirectory是基于文件系统的索引,还有基于内存等更多子类。
  • Analyzer
    文本文件在被索引或者建立索引的时候都需要经过Analyzer(分析器)处理。它负责从被索引文本文件中提取语汇单元,并提出剩下的无用信息。Analyzer是一个抽象类,Lucene提供了几个实现类,不过对中文分词的效果不太好,网上有几个比较好的开源中文分词库IKAnalyzermmseg
  • Document
    Document(文档)对象代表一些域(Field)的集合。你可以将Document理解为虚拟文档—比如Web页面、E-mail信息或者文本文件---然后你可以从中取回大量的数据。
  • Field
    索引中的每个文档都包含一个或多个不同命名的域,这些鱼包含在Field类中,每个域都有一个域名和对应的域值,以及一组选项来精确控制Lucene索引操作各个域值。文档可能拥有不值一个同名的域。在这种情况下,域的值就按照索引操作顺序添加进去。在搜索时,所有域的文本就好像连接在一起,作为一个文本域来处理。

理解搜索过程的核心类

  • IndexSearcher
    IndexSearcher类用于搜索由IndexWriter类创建的索引:这个类公开了几个搜索的方法,他是链接索引的中间环节,可以将IndexSearcher类看作是一个以只读方式打开索引的类。它需要利用Direcotry实例来控制前期创建的索引,然后才能提供大量的搜索方法。该类最简单的用法如下:
    Directory dir = FSDirectory.open(new File("/tmp/index"));
    IndexSearcher searcher = new IndexSearcher(dir);
    Query q = new TermQuery(new Term("contents","lucene"));
    TopDocs hits = searcher.search(q,10);
    searcher.close();
  • Term
    Term对象是搜索功能的基本单元,与Field对象类似,Term对象包含一对字符串元素:域名和单词。
  • Query
    Lucene含有许多具体的Query(查询)子类。
  • TermQuery
    TermQuery是Lucene提供的最基本的查询类型,也是简单查询类型之一。
  • TopDocs
    TopDocs类是一个简单的指针容器,指针一般指向前N个排名的搜索结果,搜索结果即匹配查询条件的文档。TopDocs会记录前N个结果中每个结果的int docID(可以用它来回复文档)和浮点型分数

小结

本文主要是Lucene In Action 第一章的内容,通过2个例子,对lucene有了最初的认识和使用方法。

(全文完 linjl 20130904 深圳)

© 著作权归作者所有

共有 人打赏支持
粉丝 3
博文 16
码字总数 20545
作品 0
广州
加载中

评论(1)

iNVAiN_
iNVAiN_
不错的笔记,很清晰
《Linux内核设计与实现》读书笔记 - 目录 (完结)

《Linux内核设计与实现》读书笔记 - 目录 (完结) 读完这本书回过头才发现, 第一篇笔记居然是 2012年8月发的, 将近一年半的时间才看完这本书(汗!!!). 为了方便以后查看, 做个《Linux内核设计...

你的猫大哥
01/14
0
0
告诉你1年读100本书的方法

《书都不会读,你还想成功》是一本小说,由韩国作家二志成和郑会一合著,书的内容为一个焦躁的职场人士通过读书的方式,彻底改变了自己的思维方式,进而改变了自己的生活的故事。 下面就说说...

anda0109
2016/12/22
0
0
UNIX网络编程卷2进程间通信读书笔记汇总

UNIX网络编程卷2进程间通信读书笔记(一)—概述 http://blog.chinaunix.net/u/22935/article527112.html UNIX网络编程卷2进程间通信读书笔记(二)—管道 (1) http://blog.chinaunix.net/...

长平狐
2012/09/03
185
0
用骆驼祥子读书笔记来解答ZBLOG博客写作的3个技巧[图]

建设博客已经半年了,准确的说应该是7个月了吧,虽然没有取得什么好的进展,但毕竟一直在努力,主要是内容建设上比较麻烦,很难像大站一样获得大量的内容,这是非常头疼的问题。 总之,个人也...

原创小博客
07/11
0
0
2018开始读书吧——关于读书的思考

1.封目序尾 所谓的封目序尾就是:读书前要先看封面、目录、序言、结尾。 封面:题目是作者花了很长的时间才总结出的,是对这本书的一句话概括,是这本书的核心价值。 目录:是对这本书的梳理...

尚洪范
01/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

申请Let's Encrypt永久免费SSL证书

环境安装 1、安装git yum install git-core 2、安装python 系统自带 不用安装 只要版本大于2.7即可。 获取Let's Encrypt免费SSL证书 先停止nginx 在阿里云安全组里加入 443端口的入规则 git ...

HGMrWang
35分钟前
1
0
如何使用playframework进行更好的开发

1: 自定义基类Controller 相信刚开始使用Play的人写的Controller 都继承于 play.mvc.Controller , 但这并不是一个很好的选择,自建基类Controller可以扩展更多的功能。 1.1 验证功能。 后台...

tuerqidi
40分钟前
4
0
解决ubuntu下root用户 不能ftp登陆的问题

解决ubuntu下root用户 不能ftp登陆的问题 一般情况下,由于种种原因ftp是不让root用户远程登陆,但只要你修改以个文件就可以登陆了. 注释掉 /etc/ftpusers 中的root即可 (最后重启vsftpd serv...

15834278076
51分钟前
0
0
《JavaScript高级程序设计(第3版)》阅读笔记

第6章 面向对象的程序设计 6.2 创建对象 6.2.1 工厂模式 JavaScript创建对象(一)—— 工厂模式 6.2.2 构造函数模式 JavaScript创建对象(二)——构造函数模式 6.2.3 原型模式 JavaScript...

Bob2100
56分钟前
1
0
Windows小技巧 – Win+R提高Windows使用效率

追求效率的朋友都需要一款顺手的快速启动工具,Win 平台上有键盘流的RunZ、Listary、ALTRun、Launchy、Wox 和图标流的 Fences、Rolan、 WinLaunch 等,而 Mac 上也有 Alfred、Spotlight。 而...

QQZZFT
59分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部