Lucene第一个入门学习例子

看Lucene in Action的时候,练习的一个入门例子。

在使用Lucene进行文本内容搜索前,需要先对指定的目录下的文件进行建立索引,代码如下:

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.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

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

		long start = System.currentTimeMillis();
		Indexer indexer = null;
		try {
			indexer = new Indexer(indexDir);
		} catch (IOException e) {
			e.printStackTrace();
		}
		int numIndexed = 0;
		try {
			numIndexed = indexer.index(dataDir, new TextFilesFilter());
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				indexer.close();
			} catch (IOException e) {
				e.printStackTrace();
			} 
		}
		long end = System.currentTimeMillis();
		System.out.println("Indexing " + numIndexed + " files took " + (end - start) + "mi");
	}

	private IndexWriter writer;

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

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

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

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

	/**
	 * 声明三个索引的查询域,一个contents,一个filename,一个fullpath
	 * @param f
	 * @return
	 * @throws Exception
	 */
	protected Document getDocument(File f) throws Exception {
		Document doc = new Document();
		doc.add(new Field("contents", new FileReader(f)));
		doc.add(new Field("filename", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		doc.add(new Field("fullpath", f.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		return doc;
	}

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

在使用命令方式执行后在传入的目录下会生成如图的文件:

成功生成索引后,便可以进行基本的搜索了,检索代码如下:

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

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

	private static void search(String indexDir, String q) throws IOException, ParseException {
		Directory dir = FSDirectory.open(new File(indexDir));
		DirectoryReader reader = DirectoryReader.open(dir);
		IndexSearcher is = new IndexSearcher(reader);
		// 每个Term都对应一个Field域
		Query query = new TermQuery(new Term("contents", q));
		long start = System.currentTimeMillis();
		TopDocs hits = is.search(query, 10);
		long end = System.currentTimeMillis();
		System.err.println("Found " + hits.totalHits + " document(s) (in " + (end - start) + " mi) that matched query ‘" + q + "‘ :");
		for(ScoreDoc scoreDoc : hits.scoreDocs) {
			Document doc = is.doc(scoreDoc.doc);
			System.out.println(doc.get("fullpath"));
			System.out.println(Arrays.toString(doc.getValues("filename")));
			System.out.println(doc.get("contents"));
		}

		Query qu = new TermQuery(new Term("filename", "1.txt"));
		TopDocs hits1 = is.search(qu, 10);
		for(ScoreDoc score : hits1.scoreDocs) {
			System.out.println(is.doc(score.doc).get("fullpath"));
		}
		reader.close();
		dir.close();
	}
}

命令中执行如搜索目录下是否有“Hi”的单词,返回结果为:

Lucene第一个入门学习例子

时间: 2024-10-12 03:25:39

Lucene第一个入门学习例子的相关文章

C++ Primer快速学习 第一章 入门

很多人说C++Primer不适合于入门,本系列入门文章向大家证明了:这是一个谎言. 第一章 入门 本章介绍 C++ 的大部分基本要素:内置类型.库类型.类类型.变量.表 达式.语句和函数. 1.1. 编写简单的 C++ 程序 每个 C++ 程序都包含一个或多个 函数 ,而且必须有一个命名为 main.函数 由执行函数功能的语句序列组成.操作系统通过调用 main 函数来执行程序, main 函数则执行组成自己的语句并返回一个值给操作系统. 下面是一个简单的 main 函数,它不执行任何功能,只是

Lucene.net入门学习系列(1)

Lucene.net入门学习系列(1)-分词 Lucene.net入门学习系列(2)-创建索引 Lucene.net入门学习系列(3)-全文检索 这几天在公司实习的时候闲的蛋疼,翻了一下以往的教程和博客,看到了Lucene.net.原本想学着写一个系列的博文,由于本人水平有限,一直找不到适合的内容来写,干脆就写一个简单的Lucene.net系列文章吧.希望和大家一起学习,一起进步,有什么写错了或者有什么建议欢迎提出来. 一.引言 先说一说什么是Lucene.net.Lucene.net是Luce

汇编入门学习笔记 (三) —— 第一个程序

疯狂的暑假学习之  汇编入门学习笔记 (三)-- 第一个程序 参考:<汇编语言> 王爽  第四章 1.一个源程序从写到执行的过程 第一步:编写汇编源程序 第二步:对源程序进行编译连接 第三步:在操作系统中执行 2.源程序 代码: assume cs:first first segment start: mov ax,2 add ax,ax add ax,ax mov ax,4C00H int 21H first ends end start 代码解释: assume .segment.ends

FPGA入门学习第一课:二分频器

分频器还是比较简单的,一般的思路是:每数几个时钟就输出一个时钟.最简单的当数二分频器了,每当时钟上升沿(或下降沿)就把输出翻转一下.这样就刚好实现了二分频器了. 网上也搜到了最简实现”二分频最简单了,一句话就可以了:               always @ (negedge clk)        clk_2<=~clk_2;“ 但仿真时却发现无法输出 分析是因为输出信号的初始状态不确定造成的,于是加了一句初始化,就可以正常分频了 但观察他们生成的逻辑结构图是一样的 完整代码如下: mod

正则表达式入门学习

\b-元字符,代表单词的开头或结尾,也就是单词的分界处. \bHi\b     下列未进行说明的都是元字符. .  匹配除了换行符以外的任意字符. * 指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配.(不包含换行的字符) \bHi\b.*\bLucy\b \d 匹配一位数字(0或1或2......或9)  0\d\d-\d\d\d\d\d\d\d\d - 不是元字符 ,只匹配它本身. 避免重复 0\d{2}-\d{8}  {2}({8})指前面\d必须连续重复匹配2次(8次). \

OpenGL入门学习

说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色来做吗?显然是不行的. 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物. OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性. 1.与C语言紧密结合. OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的

Crypto++入门学习笔记(DES、AES、RSA、SHA-256)

最先附上 下载地址 背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以skip): 最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后对一些数据进行一些加密解密的操作. 笔者之前没接触过任何加密解密方面的知识(当然,把每个字符的ASCII值加1之流对明文进行加密的“趣事”还是干过的,当时还很乐在其中.),甚至一开始连Crypto++的名字都没有听过,被BS了之后,就开始了Crypto++的入门探索过程. 最初,大概知道了要了解两大类算法中的几个算法——对称加密算法:D

MongoDB入门学习(三):MongoDB的增删查改

对于我们这种菜鸟来说,最重要的不是数据库的管理,也不是数据库的性能,更不是数据库的扩展,而是怎么用好这款数据库,也就是一个数据库提供的最核心的功能,增删查改. 因为MongoDB存储数据都是以文档的模式,所以在操作它的数据时,也是以文档为单位的.那么我们实现增删查改也是以文档为基础,不知道文档是什么的同学可以看看上篇介绍的基本概念. 1.插入文档 向MongoDB集合中插入文档的基本方法是insert: 单个插入 > document = {key : value} > db.collecti

java入门学习:Java中的main()方法详解

本文来源:http://www.zretc.com/technologyDetail/445.html 在Java入门学习中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等. 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这