lucene快速入门---一个例子读懂

一、一句话描述

                  Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。

二、举例应用

                  Eclipse:基于Java的开放开发平台,帮助部分的全文索引使用了Lucene

三、例子

<span style="font-size:18px;">import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class CreateLuceneIndex {

	public static void main(String[] args) {
		if (args == null || args.length <= 0) {
			args = new String[] { "-index", "F:\\lucene-4.10.2\\index", "-docs", "F:\\lucene-4.10.2\\lucene-4.10.2\\docs" };
		}
		String indexPath = ""; // 索引文件保存的路径
		String docsPath = null; // 资源文件所在目录
		boolean create = true;
		for (int i = 0; i < args.length; i++) {
			if ("-index".equals(args[i])) {
				indexPath = args[i + 1];
				i++;
			} else if ("-docs".equals(args[i])) {
				docsPath = args[i + 1];
				i++;
			} else if ("-update".equals(args[i])) {
				create = false;
			}
		}

		if (docsPath == null) {
			System.err.println("资源文件所在目录为空,请指定资源文件所在目录!!!");
			System.exit(1);
		}

		final File docDir = new File(docsPath);
		if (!docDir.exists() || !docDir.canRead()) {
			System.out.println("资源文件目录 '" + docDir.getAbsolutePath() + "' 不存在或不可读,请检查!");
			System.exit(1);
		}

		Date start = new Date();
		try {
			System.out.println("建立索引文件到该目录 '" + indexPath + "'...");

			Directory dir = FSDirectory.open(new File(indexPath));
			Analyzer analyzer = new StandardAnalyzer();
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
			if (create) {
				// 创建新的索引文件,删除所有其他的索引文件
				// (指的是该资源文件目录下的旧的索引文件,其他资源的索引文件不影响)
				iwc.setOpenMode(OpenMode.CREATE);
			} else {
				// 如果有旧的索引文件,则更新索引文件
				iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
			}
			IndexWriter writer = new IndexWriter(dir, iwc);
			indexDocs(writer, docDir);
			writer.close();
			Date end = new Date();
			System.out.println(end.getTime() - start.getTime() + " total milliseconds");
		} catch (IOException e) {
			System.out.println(" caught a " + e.getClass() + "\n with message: " + e.getMessage());
		}
	}

	/**
	 * 将资源文件索引到指定目录下,生成磁盘的索引文件
	 * 
	 * @param writer
	 *            索引文件
	 * @param file
	 *            资源文件
	 */
	static void indexDocs(IndexWriter writer, File file) throws IOException {
		if (!file.canRead()) {
			return;
		}
		if (file.isDirectory()) {
			String[] files = file.list();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					indexDocs(writer, new File(file, files[i]));
				}
			}
		} else {
			FileInputStream fis;
			try {
				fis = new FileInputStream(file);
			} catch (FileNotFoundException fnfe) {
				return;
			}
			try {

				// 每一个文档最终被封装成了一个 Document 对象
				// Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。
				// 一个 Document 对象由多个 Field 对象组成的。
				// 可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。
				Document doc = new Document();
				// Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。
				Field pathField = new StringField("path", file.getPath(), Field.Store.YES);
				// pathField指的是资源文件的路径的field
				doc.add(pathField);
				// 这个field指的是最后的修改时间
				doc.add(new LongField("modified", file.lastModified(), Field.Store.NO));

				// 把资源文件中的内容分词后,索引到索引文件中,指定为UTF-8编码
				doc.add(new TextField("contents", new BufferedReader(new InputStreamReader(fis, "utf-8"))));

				if (writer.getConfig().getOpenMode() == OpenMode.CREATE) {
					System.out.println("adding " + file);
					writer.addDocument(doc);
				} else {
					System.out.println("updating " + file);
					writer.updateDocument(new Term("path", file.getPath()), doc);
				}
			} finally {
				fis.close();
			}
		}

	}
}</span>


<span style="font-size:14px;"><strong>import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
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.TopDocs;
import org.apache.lucene.store.FSDirectory;

public class SearchFiles {

	public static void main(String[] args) throws Exception {
		args = new String[] { 
				"-index", 
				"F:\\lucene-4.10.2\\index" 
			};
		if (args.length > 0
				&& ("-h".equals(args[0]) || "-help".equals(args[0]))) {
			System.exit(0);
		}

		String index = "index";
		String field = "contents";
		String queries = null;
		int repeat = 0;
		boolean raw = false;
		String queryString = null;
		int hitsPerPage = 10;

		for (int i = 0; i < args.length; i++) {
			if ("-index".equals(args[i])) {
				index = args[i + 1];
				i++;
			} else if ("-field".equals(args[i])) {
				field = args[i + 1];
				i++;
			} else if ("-queries".equals(args[i])) {
				queries = args[i + 1];
				i++;
			} else if ("-query".equals(args[i])) {
				queryString = args[i + 1];
				i++;
			} else if ("-repeat".equals(args[i])) {
				repeat = Integer.parseInt(args[i + 1]);
				i++;
			} else if ("-raw".equals(args[i])) {
				raw = true;
			} else if ("-paging".equals(args[i])) {
				hitsPerPage = Integer.parseInt(args[i + 1]);
				if (hitsPerPage <= 0) {
					System.err
							.println("最少每页有1条数据");
					System.exit(1);
				}
				i++;
			}
		}

		IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(
				index)));
		IndexSearcher searcher = new IndexSearcher(reader);
		// :Post-Release-Update-Version.LUCENE_XY:
		Analyzer analyzer = new StandardAnalyzer();

		BufferedReader in = null;
		if (queries != null) {
			in = new BufferedReader(new InputStreamReader(new FileInputStream(
					queries), "utf-8"));
		} else {
			in = new BufferedReader(new InputStreamReader(System.in,
					"utf-8"));
		}
		// :Post-Release-Update-Version.LUCENE_XY:
		QueryParser parser = new QueryParser(field,
				analyzer);
		while (true) {
			if (queries == null && queryString == null) { // prompt the user
				System.out.println("输入查询关键字: ");
			}

			String line = queryString != null ? queryString : in.readLine();

			if (line == null || line.length() == -1) {
				break;
			}

			line = line.trim();
			if (line.length() == 0) {
				break;
			}

			Query query = parser.parse(line);
			System.out.println("Searching for: " + query.toString(field));

			if (repeat > 0) { // repeat & time as benchmark
				Date start = new Date();
				for (int i = 0; i < repeat; i++) {
					searcher.search(query, null, 100);
				}
				Date end = new Date();
				System.out.println("Time: " + (end.getTime() - start.getTime())
						+ "ms");
			}

			doPagingSearch(in, searcher, query, hitsPerPage, raw,
					queries == null && queryString == null);

			if (queryString != null) {
				break;
			}
		}
		reader.close();
	}

	public static void doPagingSearch(BufferedReader in,
			IndexSearcher searcher, Query query, int hitsPerPage, boolean raw,
			boolean interactive) throws IOException {

		// Collect enough docs to show 5 pages
		TopDocs results = searcher.search(query, 5 * hitsPerPage);
		ScoreDoc[] hits = results.scoreDocs;

		int numTotalHits = results.totalHits;
		System.out.println(numTotalHits + " total matching documents");

		int start = 0;
		int end = Math.min(numTotalHits, hitsPerPage);

		while (true) {
			if (end > hits.length) {
				System.out
						.println("Only results 1 - " + hits.length + " of "
								+ numTotalHits
								+ " total matching documents collected.");
				System.out.println("Collect more (y/n) ?");
				String line = in.readLine();
				if (line.length() == 0 || line.charAt(0) == 'n') {
					break;
				}

				hits = searcher.search(query, numTotalHits).scoreDocs;
			}

			end = Math.min(hits.length, start + hitsPerPage);

			for (int i = start; i < end; i++) {
				if (raw) { // output raw format
					System.out.println("doc=" + hits[i].doc + " score="
							+ hits[i].score);
					continue;
				}

				Document doc = searcher.doc(hits[i].doc);
				String path = doc.get("path");
				if (path != null) {
					System.out.println((i + 1) + ". " + path);
					String title = doc.get("title");
					if (title != null) {
						System.out.println("   Title: " + doc.get("title"));
					}
				} else {
					System.out.println((i + 1) + ". "
							+ "No path for this document");
				}

			}

			if (!interactive || end == 0) {
				break;
			}

			if (numTotalHits >= end) {
				boolean quit = false;
				while (true) {
					System.out.print("Press ");
					if (start - hitsPerPage >= 0) {
						System.out.print("(p)revious page, ");
					}
					if (start + hitsPerPage < numTotalHits) {
						System.out.print("(n)ext page, ");
					}
					System.out
							.println("(q)uit or enter number to jump to a page.");

					String line = in.readLine();
					if (line.length() == 0 || line.charAt(0) == 'q') {
						quit = true;
						break;
					}
					if (line.charAt(0) == 'p') {
						start = Math.max(0, start - hitsPerPage);
						break;
					} else if (line.charAt(0) == 'n') {
						if (start + hitsPerPage < numTotalHits) {
							start += hitsPerPage;
						}
						break;
					} else {
						int page = Integer.parseInt(line);
						if ((page - 1) * hitsPerPage < numTotalHits) {
							start = (page - 1) * hitsPerPage;
							break;
						} else {
							System.out.println("No such page");
						}
					}
				}
				if (quit)
					break;
				end = Math.min(numTotalHits, start + hitsPerPage);
			}
		}
	}
}</strong></span>


### 回答1: lucene-core-4.9.0.jar是Lucene搜索引擎的核心库文件,它是一个用Java语言编写的开源软件,主要用于实现全文搜索和索引功能。 Lucene一个高性能的全文搜索引擎库,它提供了一系列用于创建、更新和查询索引的API。对于需要在大量文本数据中进行快速和准确搜索的应用程序来说,Lucene一个非常好的选择。 核心库文件lucene-core-4.9.0.jar包含了Lucene搜索引擎的所有核心功能,包括索引的创建和管理、搜索查询的执行、搜索结果的排序和过滤等。通过引入该库文件,开发人员可以在自己的应用程序中使用Lucene提供的功能来实现文本数据的全文索引和搜索。 在使用Lucene时,开发人员可以根据自己的需要,使用lucene-core-4.9.0.jar的API来创建索引,将文档进行分词、过滤和标准化处理,然后将处理后的文档添加到索引中。当需要进行搜索时,可以使用Lucene提供的查询语法和查询API,对索引中的文档进行高效的全文搜索。 除了lucene-core-4.9.0.jar之外,Lucene还提供了其他一些相关的jar文件,例如lucene-analyzers-common.jar和lucene-queryparser.jar等,它们可以用于分析和处理文本数据,以及解析查询语法。通过组合使用这些库文件,开发人员可以更灵活地构建自己的全文搜索应用程序。 总之,lucene-core-4.9.0.jar是Lucene搜索引擎的核心库文件,它提供了一系列用于创建、更新和查询文本数据索引的API,为开发人员提供了实现全文搜索功能的便利。 ### 回答2: lucene-core-4.9.0.jar是Lucene项目的核心库,它是用Java编写的全文搜索引擎库。Lucene一个开源项目,旨在提供一个强大且高效的搜索引擎,用于构建各种应用程序,如网站搜索,文本分析和信息检索等。 lucene-core-4.9.0.jar提供了许多关键的功能和类,包括索引创建和管理,查询解析和执行,文本分析和词法处理等。通过使用这个库,开发人员可以轻松地构建自己的搜索应用程序,并实现快速和准确的搜索功能。 在Lucene的使用过程中,开发人员可以通过创建索引来处理需要搜索的文档集合。索引是一个用于快速查找和检索文档的数据结构,它包含了文档中的关键词、位置和其他重要信息。lucene-core-4.9.0.jar提供了一些类来帮助创建和维护索引,在搜索时可以快速定位相关文档。 另外,lucene-core-4.9.0.jar还提供了丰富的查询语法和API,以便开发人员可以根据特定的需求构建和执行复杂的查询。这些查询可以包括布尔逻辑、过滤器、范围查询和模糊匹配等多种形式。通过使用Lucene的查询功能,用户可以快速找到符合其需求的相关文档。 总之,lucene-core-4.9.0.jar是Lucene项目的核心库,提供了全文搜索引擎的关键功能和类。它可以帮助开发人员构建强大的搜索应用程序,实现快速和准确的搜索功能。 ### 回答3: lucene-core-4.9.0.jar 是一个用于构建搜索引擎的Java库。Lucene一个开源的全文搜索引擎工具包,它提供了用于索引和搜索文本的功能。 lucene-core-4.9.0.jar 是Lucene库的核心组件,用于实现基本的搜索和索引功能。它包含了索引文档和搜索相关内容所需的所有必要类和方法。这个.jar文件是由Lucene 4.9.0版本的源代码编译而成的。 使用 lucene-core-4.9.0.jar,我们可以很方便地在自己的应用程序中实现搜索功能。首先,我们需要构建一个索引,将要搜索的文本内容进行索引化。然后,我们可以使用 Lucene 提供的 API 进行搜索操作,通过关键字或特定的查询语句来搜索索引中的内容。Lucene 提供了丰富的查询语法和搜索算法,可以根据需求进行高级的搜索操作,如模糊搜索、排序、过滤等。 通过使用 lucene-core-4.9.0.jar,我们可以为我们的应用程序添加强大的搜索能力,无论是搜索文件、数据库、网站内容或是其他结构化的数据。Lucene 库已经在众多应用中得到了广泛的应用,包括网站搜索引擎、文档管理系统、电子邮件客户端等。 总之,lucene-core-4.9.0.jar 是一个功能强大且灵活的Java库,可以帮助开发人员快速构建搜索引擎和实现全文搜索功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值