lucene的使用

2019-03-27 01:22|来源: 网路

使用luncene3.6

下载地址   http://www.apache.org/dyn/closer.cgi/lucene/java/3.6.1

分词器使用 mmseg4j

下载地址  http://code.google.com/p/mmseg4j/downloads/list


项目中使用到的jar包有  :

lucene-3.6.1/lucene-core-3.6.1.jar(核心包)

lucene-3.6.1/contrib/lucene-analyzers-3.6.1.jar(分词包)

lucene-3.6.1/contrib/lucene-highlighter-3.6.1.jar(高亮包)

mmseg4j-1.8.3/mmseg4j-all-1.8.3.jar(第三方分词器,因为luncene自带的分词器没有词库,汉字都是一个一个拆开的)


使用时记得设置词库的路径

mmseg4j-1.8.3/data



package lucene;

import java.io.File;
import java.io.StringReader;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import com.chenlb.mmseg4j.analysis.MaxWordAnalyzer;

public class LuceneSearch {
	
	//mmseg4j词库路径
	private static final String DISC_URL = "D:/My Documents/Downloads/mmseg4j-1.8.3/data";
	//指定分词器 StandardAnalyzer、MaxWordAnalyzer、SimpleAnalyzer、ComplexAnalyzer
	private static Analyzer analyzer = new MaxWordAnalyzer(new File(DISC_URL));
	//lucene版本
	private static Version version = Version.LUCENE_36;
	//指定索引位置   RAMDirectory(内存)、FSDirectory(文件)
	private static Directory directory = new RAMDirectory();
	//配置
	private static IndexWriterConfig conf = new IndexWriterConfig(version,analyzer);
	//配置IndexWriter
	private static IndexWriter writer;
	static{
		try {
			writer = new IndexWriter(directory, conf);
		} catch (Exception e) {
		}
	}

	/**
	 * 全量索引
	 * @Author TangJiaZhi
	 */
	public void fullIndex(Document[] documentes) throws Exception {
		
		writer.deleteAll();
		for (Document document : documentes) {
			writer.addDocument(document);
		}
		writer.commit();
//		writer.close();
	}
	
	
	/**
	 * 根据id删除索引
	 * @Author TangJiaZhi
	 */
	public void deleteIndex(Document document)throws Exception{
		Term term = new Term("id", document.get("id"));
		writer.deleteDocuments(term);
		writer.commit();
	}
	
	/**
	 * 根据id增量索引
	 * @Author TangJiaZhi
	 */
	public void updateIndex(Document[] documentes) throws Exception{
		for (Document document : documentes) {
			Term term = new Term("id", document.get("id"));
			writer.updateDocument(term, document);
		}
		writer.commit();
//		writer.close();
	}
	
	/**
	 * 直接查询
	 * @Author TangJiaZhi
	 */
	public void simpleSearch(String filedStr,String queryStr,int page, int pageSize) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		TopScoreDocCollector topCollector = TopScoreDocCollector.create(searcher.maxDoc(), false);
		
		Term term = new Term(filedStr, queryStr);
		Query query = new TermQuery(term);
		searcher.search(query, topCollector);
		ScoreDoc[] docs = topCollector.topDocs((page-1)*pageSize, pageSize).scoreDocs;
		
		printScoreDoc(docs, searcher);
	}
	
	/**
	 * 高亮查询
	 * @Author TangJiaZhi
	 */
	public void highLightSearch(String filedStr,String queryStr,int page, int pageSize) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		TopScoreDocCollector topCollector = TopScoreDocCollector.create(searcher.maxDoc(), false);
		
		Term term = new Term(filedStr, queryStr);
		Query query = new TermQuery(term);
		searcher.search(query, topCollector);
		ScoreDoc[] docs = topCollector.topDocs((page-1)*pageSize, pageSize).scoreDocs;
		
		
		Formatter formatter = new SimpleHTMLFormatter("<span>","</span>");
		Highlighter highlighter = new Highlighter(formatter, new QueryScorer(query));
		for (int i = 0; i < docs.length; i++) {
			List<Fieldable> list = searcher.doc(docs[i].doc).getFields();
			for (Fieldable fieldable : list) {
				String fieldName = fieldable.name();
				String fieldValue = fieldable.stringValue();
				TokenStream ts = analyzer.tokenStream(fieldName, new StringReader(fieldValue));
				String frament = highlighter.getBestFragment(ts, fieldValue); 
				System.out.println(fieldName+" : "+frament);
			}
		}
	}
	
	/**
	 * 根据前缀查询
	 * @Author TangJiaZhi
	 */
	public void prefixSearch(String filedStr,String queryStr) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		
		Term term = new Term(filedStr, queryStr);
		Query query = new PrefixQuery(term);
		
		ScoreDoc[] docs = searcher.search(query, 3).scoreDocs;
		printScoreDoc(docs, searcher);
	}
	
	/**
	 * 通配符查询
	 * @Author TangJiaZhi
	 */
	public void wildcardSearch(String filedStr,String queryStr) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		
		Term term = new Term(filedStr, queryStr);
		Query query = new WildcardQuery(term);
		
		
		
		ScoreDoc[] docs = searcher.search(query, 3).scoreDocs;
		printScoreDoc(docs, searcher);
	}
	
	/**
	 * 分词查询
	 * @Author TangJiaZhi
	 */
	public void analyzerSearch(String filedStr,String queryStr) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		
		QueryParser queryParser = new QueryParser(version, filedStr, analyzer);
		Query query = queryParser.parse(queryStr);
		
		ScoreDoc[] docs = searcher.search(query, 3).scoreDocs;
		printScoreDoc(docs, searcher);
	}
	
	/**
	 * 多属性分词查询
	 * @Author TangJiaZhi
	 */
	public void multiAnalyzerSearch(String[] filedStr,String queryStr) throws Exception{
		IndexReader reader = IndexReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(reader);
		QueryParser queryParser = new MultiFieldQueryParser(version, filedStr, analyzer);
		Query query = queryParser.parse(queryStr);
		
		ScoreDoc[] docs = searcher.search(query, 3).scoreDocs;
		printScoreDoc(docs, searcher);
	}
	
	public void printScoreDoc(ScoreDoc[] docs,IndexSearcher searcher)throws Exception{
		for (int i = 0; i < docs.length; i++) {
			List<Fieldable> list = searcher.doc(docs[i].doc).getFields();
			for (Fieldable fieldable : list) {
				String fieldName = fieldable.name();
				String fieldValue = fieldable.stringValue();
				System.out.println(fieldName+" : "+fieldValue);
			}
		}
	}

	public static void main(String[] args) throws Exception {
		LuceneSearch t = new LuceneSearch();
		Document d1 = new Document();
		d1.add(new Field("id", "1", Store.YES, Index.ANALYZED));
		d1.add(new Field("name", "苦逼的程序员", Store.YES, Index.ANALYZED));
		Document d2 = new Document();
		d2.add(new Field("id", "2", Store.YES, Index.ANALYZED));
		d2.add(new Field("name", "2b的程序员", Store.YES, Index.ANALYZED));
		Document[] documentes = {d1,d2};
		
		System.out.println("--------------------------全量索引--------------------------");
		t.fullIndex(documentes);
		t.simpleSearch("name", "程序", 1, 10);
		t.highLightSearch("name", "程序", 1, 10);
		
		System.out.println("--------------------------增量索引--------------------------");
		d1.removeField("name");
		d1.add(new Field("name", "程序", Store.YES, Index.ANALYZED));
		t.updateIndex(documentes);
		t.simpleSearch("name", "程序", 1, 10);
		
		System.out.println("--------------------------删除索引--------------------------");
		t.deleteIndex(d1);
		t.simpleSearch("name", "2b", 1, 10);
		
		System.out.println("--------------------------分词查询--------------------------");
		t.multiAnalyzerSearch(new String[]{"id","name"}, "苦逼的程序员");
		
	}

}



使用QueryParser接口查询时,会根据指定的分词器对查询条件先分词再搜索

这就是为什么

t.multiAnalyzerSearch(new String[]{"id","name"}, "苦逼的程序员");

能搜索出结果的原因


不过实际项目中所要求的站内搜索直接使用lucene的子项目solr就可以轻松的实现了。



转自:http://my.oschina.net/eatsuger/blog/87119

相关问答

更多
  • lucene 使用步骤[2022-10-07]

    lucene主要完成的是Indexing&Search功能,所以一般使用步骤: 建索引、优化索引 和搜索
  • Lucene的使用[2023-06-15]

    Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。 Lucene的作者:Lucene的贡献者Doug Cutting是一位资深全文索引/检索专家,曾经是V-Twin搜索引擎(Apple的Copland操作系统的成就之一)的主要开发者,后在Excite担任高级系统架构设计师,目前从事于一些INTERNET底层架构的研究。他贡献出的Lucene的目标是为各种中小型应用程序加入全文检索功能。 Lucene的发展历程:早 ...
  • lucene怎么用[2022-07-03]

    Lucene是一个全文检索系统框架,开源的。 用起来比较方便,去Lucene的官网上下一个包并导入到你的工程中就可以调用包里面的类了。 一般的书里面介绍的版本都是1.4.3或者稍微高级一点的,不过现在lucene3.0正式发布,一些函数调用方法已经改变了,你可以下载一个版本低一点的Lucene比较适合学习~ 当然你直接从3.0入手的话网上资料也是非常丰富的~
  • lucene 怎么读[2022-08-02]

    路(第一声)森(第三声)
  • lucene怎么读[2022-03-23]

    [lu:sən]鲁森
  • 这不是很简单的问题?把HTML目录设置成lucene的索引目录,再用程序读出HTML文件代码,再索引HTML文件内容
  • lucene 例子[2024-02-23]

    http://www.chedong.com/tech/lucene.htmlLucene:基于Java的全文检索引擎简介例子所使用的Lucene版本比较低图书:征服Ajax+Lucene构建搜索引擎 http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=BB071056621Lucene IN ACTION中文版 http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=10033228
  • http://www.chedong.com/tech/lucene.html Lucene:基于Java的全文检索引擎简介 例子所使用的Lucene版本比较低 图书: 征服Ajax+Lucene构建搜索引擎 http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=BB071056621 Lucene IN ACTION中文版 http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=10033228
  • 我认为你指的是使用QueryParser对象解析布尔查询,对吗? Lucene查询语法文档应该有你需要的一切。 I presume you are referring to parsing boolean queries using the QueryParser object, correct? The Lucene query syntax documentation should have everything you need.
  • Lucene是一个倒置的全文索引。 这意味着它需要所有的文档,将它们分成单词,然后为每个单词生成一个索引。 由于索引是一个精确的字符串匹配,无序,它可以非常快。 假设, varchar字段上的SQL无序索引可能会很快,实际上我认为你会发现大型数据库可以在这种情况下很快地做一个简单的字符串相等查询。 Lucene不必优化事务处理。 当您添加文档时,它不需要确保查询立即查看。 并且不需要优化现有文档的更新。 但是,一天结束的时候,如果你真的想知道,你需要阅读源码。 毕竟,你引用的两件事都是开源的。 Lucene ...