《Lucene In Action》 02 Hello Lucene World

Indexer:

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

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

// From chapter 1

/**
 * This code was originally written for
 * Erik‘s Lucene intro java.net article
 */
public class Indexer {

  public static void main(String[] args) throws Exception {
    if (args.length != 2) {
      throw new IllegalArgumentException("Usage: java " + Indexer.class.getName()
        + " <index dir> <data dir>");
    }
    String indexDir = args[0];         //1
    String dataDir = args[1];          //2

    long start = System.currentTimeMillis();
    Indexer indexer = new Indexer(indexDir);
    int numIndexed;
    try {
      numIndexed = indexer.index(dataDir, new TextFilesFilter());
    } finally {
      indexer.close();
    }
    long end = System.currentTimeMillis();

    System.out.println("Indexing " + numIndexed + " files took "
      + (end - start) + " milliseconds");
  }

  private IndexWriter writer;

  public Indexer(String indexDir) throws IOException {
    Directory dir = FSDirectory.open(new File(indexDir));
    writer = new IndexWriter(dir,            //3
                 new StandardAnalyzer(       //3
                     Version.LUCENE_30),//3
                 true,                       //3
                             IndexWriter.MaxFieldLength.UNLIMITED); //3
  }

  public void close() throws IOException {
    writer.close();                             //4
  }

  public int index(String dataDir, FileFilter filter)
    throws Exception {

    File[] files = new File(dataDir).listFiles();

    for (File f: files) {
      if (!f.isDirectory() &&
          !f.isHidden() &&
          f.exists() &&
          f.canRead() &&
          (filter == null || filter.accept(f))) {
        indexFile(f);
      }
    }

    return writer.numDocs();                     //5
  }

  private static class TextFilesFilter implements FileFilter {
    public boolean accept(File path) {
      return path.getName().toLowerCase()        //6
             .endsWith(".txt");                  //6
    }
  }

  protected Document getDocument(File f) throws Exception {
    Document doc = new Document();
    doc.add(new Field("contents", new FileReader(f)));      //7
    doc.add(new Field("filename", f.getName(),              //8
                Field.Store.YES, Field.Index.NOT_ANALYZED));//8
    doc.add(new Field("fullpath", f.getCanonicalPath(),     //9
                Field.Store.YES, Field.Index.NOT_ANALYZED));//9
    return doc;
  }

  private void indexFile(File f) throws Exception {
    System.out.println("Indexing " + f.getCanonicalPath());
    Document doc = getDocument(f);
    writer.addDocument(doc);                              //10
  }
}

索引过程核心类:

IndexWriter

  负责新建或打开已有索引,以及向索引中添加、删除或更新被索引文档信息,一般要通过构造器传入Directory和Analyzer

Directory

  抽象类,描述了索引的存放位置

Analyzer

  负责从被索引文本中提取语汇单元,只能处理纯文本文件,如果不是纯文本,需要先转换(如使用Tika)

Document

  Document对象代表一些Field的集合

Field

  Lucene只处理从二进制文档中提取的一Field形式出现的文本,文档的元数据作为文档的不同域单独存储并索引

题外话:Lucene内核本身只处理java.lang.String、java.io.Reader和本地数字类型(int、float等)

Searcher:

import org.apache.lucene.document.Document;
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.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.util.Version;

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

// From chapter 1

/**
 * This code was originally written for
 * Erik‘s Lucene intro java.net article
 */
public class Searcher {

  public static void main(String[] args) throws IllegalArgumentException,
        IOException, ParseException {
    if (args.length != 2) {
      throw new IllegalArgumentException("Usage: java " + Searcher.class.getName()
        + " <index dir> <query>");
    }

    String indexDir = args[0];               //1
    String q = args[1];                      //2   

    search(indexDir, q);
  }

  public static void search(String indexDir, String q)
    throws IOException, ParseException {

    Directory dir = FSDirectory.open(new File(indexDir)); //3
    IndexSearcher is = new IndexSearcher(dir);   //3   

    QueryParser parser = new QueryParser(Version.LUCENE_30, // 4
                                         "contents",  //4
                     new StandardAnalyzer(          //4
                       Version.LUCENE_30));  //4
    Query query = parser.parse(q);              //4
    long start = System.currentTimeMillis();
    TopDocs hits = is.search(query, 10); //5
    long end = System.currentTimeMillis();

    System.err.println("Found " + hits.totalHits +   //6
      " document(s) (in " + (end - start) +        // 6
      " milliseconds) that matched query ‘" +     // 6
      q + "‘:");                                   // 6

    for(ScoreDoc scoreDoc : hits.scoreDocs) {
      Document doc = is.doc(scoreDoc.doc);               //7
      System.out.println(doc.get("fullpath"));  //8
    }

    is.close();                                //9
  }
}

搜索过程核心类:

IndexSearcher

  用于搜索由IndexWriter创建的索引,构造器需要传入Directory获取创建的索引。然后提供搜索方法

Term

  Term对象是搜索的基本单元(与Field类似)

Query q = new TermQuery(new Term("contents","lucene"));
TopDocs hits = searcher.search(q,10);

Query

  Query是所有查询类的基类,如TermQuery、BooleanQuery

TermQuery

  TermQuery是最基本最简单的查询类型之一,用于匹配指定域中包含指定项的文档

TopDocs

  是一个简单的指针容器,容纳查询结果

汤能养身整理,转载注明
时间: 2024-11-08 20:54:40

《Lucene In Action》 02 Hello Lucene World的相关文章

《Lucene In Action》 01 初识Lucene

基于Lucene 3.0.1 1.Lucene简单定义 Lucene是高性能.可扩展的信息检索(IR)工具库.向用户提供了简单易用的索引和搜索API,屏蔽了内部复杂而先进的信息检索技术实现过程Lucene仅仅是一个提供搜索功能的类库,你还需要根据实际情况自行完成搜索程序的其他模块(网页抓取.文档处理.服务器运行.用户界面和管理等)Lucene的核心jar包很小,只有1M左右,核心之外,存在大量的扩展模块.另外你如果寻找一些成型的网页搜索.文档处理或搜索引擎,可以在Lucene wiki的技术支持

《Netty in action》目录修复版本分享

最近阅读了Netty in action一书.深感外国友人的书籍编写能力强大.作者由简入深.精简描述了Netty的相关知识,如何使用等等. 本来想翻译一下的.尝试着翻译了一点之后.发现非常痛苦啊.ps.笔者英语不是很好. 很多时候需要自己先把英文理解成中文然后再拼凑起来.写出来的中文译文感觉好奇怪.所以就不拿出来献丑了.把网上的PDF电子书分享一下. 前段时间去找的电子书目录都存在问题的. NIA一书分为四个部分.16个章节.网上的第五版书籍是完整的.但是目录结构完全错误了.再次使用软件修复了.

【tapestry3笔记】--tapestry 初探,《 tapestry in action 》第一章学习笔记

由于要维护一个项目,要用到tapestry3这个老框架,虽然这个框架很老,但是在我看来ta的思想还是很先进的---面向组件编程. 由于网上资料少的可怜,辛苦找了很久终于找到一本名为<tapestry in action>的工具书,以下学习笔记均以此书为参考. 正文---tapestry初探 tapestry in action 第一章学习笔记 tapestry是一款以组件为核心的开发框架,组件就向一个黑盒子,我们无需关系组件是如何实现的,只需合理使用即可.这有点像jquery的插件,我们无需关

《Elixir in Action》书评及作者问答录(作者 Sergio De Simone ,译者 邵思华 发布于 2015年9月29日)

<Elixir in Action>是由Manning所出版的一本新书,本书为读者介绍了Elixir这门语言以及Erlang虚拟机,同时也讨论了与并发编程.容错以及与高可用性相关的话题.InfoQ有幸与本书的作者Sa?a Juri?进行了一次访谈. <Elixir in Action>的内容源自于Juri?在Erlang方面的经验,他为此特意创建了一个博客,为来自面向对象背景的程序员展现Erlang的优势.Juri?之后转而使用Elixir,这是一种函数式的并发编程语言,它的目标是

《ActiveMQ in Action》【PDF】下载

内容介绍TheApache ActiveMQ message broker is an open source implementation ofthe Java Message Service spec. It makes for a reliable hub in anymessage-oriented enterprise application and integrates beautifullywith Java EE containers, ESBs, and other JMSpr

《Redis in Action》笔记(一)文章投票(1)初始化数据 + 投票 + 发布文章

原书用 Python 与 Redis 进行交互,我用 PHP 来实现. 环境:LNMP(CentOS 6.6 + Nginx 1.8.0 + MySQL 5.6.23 + PHP 5.6.9)+ Redis 3.0.7 + phpredis 2.2.4 首先在 Linux 开启 Redis 服务: [[email protected] ~]# cd /usr/local/redis/ [[email protected] redis]# ./bin/redis-server ./etc/redi

Lucene in action 第一章 初识Lucene

1.3 搜索程序组件 Lucene提供搜索程序的最核心模块:索引模块和搜索模块的类库. Solr基于Lucene,提供更丰富的UI和API可以直接部署和使用 下图为搜索程序的基本框架.中间黑体部分为Lucene完成的功能,也是搜索引擎的最核心部分. 搜索引擎评价: 满足基本功能:搜索结果正确显示 搜索回复时间 扩展功能:语法纠错,关键词高亮等 1.3.1索引组件 搜索引擎原理: 朴素思想:顺序搜索 问题:速度太慢 解决:对文本内容建立索引,通过索引返回结果 1.获取内容: 网页内容:爬虫工具 文

重读《Struts In Action》

Figure   1.1. The Java Servlet API exposes the HTTP client/server protocol to the Java   platform. Struts 2 is built on top of that.   For web applications, HTTP has two hurdles to get over. It’s stateless, and it’s text based.   Don’t reinvent the w

《图解密码技术》[02] 对称密码

所谓对称密码,是指在加密和解密时使用的都是同一密钥,比如之前提到的恺撒密码.而非对称密码,也称之为公钥密码,是指在加密和解密时使用不同密钥的方式. 本章会主要介绍几种对称密码,如DES.三重DES.AES等,在这之前,要先了解一下什么是比特序列运算. 1.比特序列运算 在这之前,我们先来看一个异或运算(不同取1,相同取0),假如有二进制数01001100为A,10101010为B,则两者异或结果为C: A 0100 1100 B 1010 1010 C 1110 0110 将异或的结果C和B再进