Lucene学习笔记之(六)lucene的中文查询

本文档详细记录了使用Lucene进行中文查询的步骤,包括创建Maven项目、配置pom.xml文件,以及如何实现对已索引文档的检索操作。通过代码示例展示了关键的检索过程,并附有相关截图以便理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

步骤一:创建maven现目


步骤二:配置pom.xml文件

   <pre name="code" class="java">                 <!-- junit包
			因为是java程序,,需要用到@Test,这就是他的jar包下载。-->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<!-- lucene核心包 
			以下这三个是用在lucene的全部jar包,core是核心包,queryparser是查询jar包。
			查询被索引文件如果是全英文的情况下,pom.xml文件写这三个,就欧了!-->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-core</artifactId>
			<version>5.3.1</version>
		</dependency>

		<!-- 查询解析器 -->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-queryparser</artifactId>
			<version>5.3.1</version>
		</dependency>

		<!-- 分析器 -->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers-common</artifactId>
			<version>5.3.1</version>
		</dependency>
		<!-- 很明显,这个是查询被检索文件为全中文的情况下,
			加上以上的三个,再加上这两个就行了。
			值得提一下,“高亮显示”的jar包可加可不加,
			在这里面加上,是因为这个在后面会用到。
			但是还是建议大家把这个加上,懂得多也不是个错。
		 	-->
		<!-- 中文分词查询器smartcn -->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers-smartcn</artifactId>
			<version>5.3.1</version>
		</dependency>

		<!-- 高亮显示 -->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-highlighter</artifactId>
			<version>5.3.1</version>
		</dependency>

步骤三:开始建包写代码

/先向文档写索引

import java.nio.file.Paths;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class Indexer {

	private Integer ids[]={1,2,3};
	private String citys[]={"青岛","南京","上海"};
	private String descs[]={
			"青岛是一个漂亮的城市。",
			"南京是一个文化的城市。",
			"上海是一个繁华的城市。"
	};
	
	private Directory dir;
	
	/**
	 *实例化indexerWriter
	 * @return
	 * @throws Exception
	 */
	private IndexWriter getWriter()throws Exception{

		//中文分词器
		SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer();
		
		IndexWriterConfig iwc=new IndexWriterConfig(analyzer);
		
		IndexWriter writer=new IndexWriter(dir, iwc);
		
		return writer;
	}
	
	/**
	 * 获取indexDir
	 * @param indexDir
	 * @throws Exception
	 */
	private void index(String indexDir)throws Exception{
		
		dir=FSDirectory.open(Paths.get(indexDir));
		
		IndexWriter writer=getWriter();
		
		for(int i=0;i<ids.length;i++){
			
			Document doc=new Document();
			
			doc.add(new IntField("id", ids[i], Field.Store.YES));
			doc.add(new StringField("city",citys[i],Field.Store.YES));
			doc.add(new TextField("desc", descs[i], Field.Store.YES));
			
			writer.addDocument(doc); 
		}
		
		writer.close();
	}
	
	
	public static void main(String[] args) throws Exception {
		
		new Indexer().index("E:\\luceneDemo6");
		System.out.println("Success Indexer");
	}
	
}
演示效果如下所示:

写完索引,就该检索被索引的文档了:代码如下:

import java.io.StringReader;
import java.nio.file.Paths;

import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
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.search.highlight.Fragmenter;
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.search.highlight.SimpleSpanFragmenter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

/**
 * 
 * 通过索引字段来读取文档
 * @author LXY
 *
 */
public class ReaderByIndexerTest {

	public static void search(String indexDir, String par) throws Exception{
				
			//得到读取索引文件的路径
			Directory dir = FSDirectory.open(Paths.get(indexDir));
				
			//通过dir得到的路径下的所有的文件
			IndexReader reader = DirectoryReader.open(dir);
				
			//建立索引查询器
			IndexSearcher searcher = new IndexSearcher(reader);
				
			//中文分词器
			SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer();
				
			//建立查询解析器
			/**
			 * 第一个参数是要查询的字段;
			 * 第二个参数是分析器Analyzer
			 * */
			QueryParser parser = new QueryParser("desc", analyzer);
				
			//根据传进来的par查找
			Query query = parser.parse(par);
				
			//计算索引开始时间
			long start = System.currentTimeMillis();
				
			//开始查询
			/**
			 * 第一个参数是通过传过来的参数来查找得到的query;
			 * 第二个参数是要出查询的行数
			 * */
			TopDocs topDocs = searcher.search(query, 10);
				
			//索引结束时间
			long end = System.currentTimeMillis();
				
			System.out.println("匹配"+par+",总共花费了"+(end-start)+"毫秒,共查到"+topDocs.totalHits+"条记录。");
				
				
			//高亮显示start
				
			//算分
			QueryScorer scorer=new QueryScorer(query);
				
			//显示得分高的片段
			Fragmenter fragmenter=new SimpleSpanFragmenter(scorer);
				
		//设置标签内部关键字的颜色
		//第一个参数:标签的前半部分;第二个参数:标签的后半部分。
		SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("<b><font color='red'>","</font></b>");
				
			//第一个参数是对查到的结果进行实例化;第二个是片段得分(显示得分高的片段,即摘要)
				Highlighter highlighter=new Highlighter(simpleHTMLFormatter, scorer);
				
				//设置片段
				highlighter.setTextFragmenter(fragmenter);
				
				//高亮显示end
				
				//遍历topDocs
				/**
				 * ScoreDoc:是代表一个结果的相关度得分与文档编号等信息的对象。
				 * scoreDocs:代表文件的数组
				 * @throws Exception 
				 * */
				for(ScoreDoc scoreDoc : topDocs.scoreDocs){
					
					//获取文档
					Document document = searcher.doc(scoreDoc.doc);
					
					//输出全路径
					System.out.println(document.get("city"));
					System.out.println(document.get("desc"));
					
					String desc = document.get("desc");
					if(desc!=null){
						
						//把全部得分高的摘要给显示出来
						
			//第一个参数是对哪个参数进行设置;第二个是以流的方式读入
			TokenStream tokenStream=analyzer.tokenStream("desc", new StringReader(desc));
						
			//获取最高的片段
			System.out.println(highlighter.getBestFragment(tokenStream, desc));
				}
		}
				
		reader.close();
	}
			
			
	//开始测试
	public static void main(String[] args) {
				
		//索引指定的路径
		String indexDir = "E:\\luceneDemo6";
				
		//查询的字段
		String par = "南京文明";
				
		try {
					
			search(indexDir,par);
					
		} catch (Exception e) {
		// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}		
}
显示效果为:


注意 看一下下面的截图:


为什么会有标签呢?

看一下的代码:
//********高亮显示start*******
	//算分
	QueryScorer scorer=new QueryScorer(query);
	//显示得分高的片段
       Fragmenter fragmenter=new SimpleSpanFragmenter(scorer);
       //设置标签内部关键字的颜色
     //第一个参数:标签的前半部分;第二个参数:标签的后半部分。
SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("<b><font color='red'>","</font></b>");
//第一个参数是对查到的结果进行实例化;第二个是片段得分(显示得分高的片段,即摘要)
Highlighter highlighter=new Highlighter(simpleHTMLFormatter, scorer);
		//设置片段
		highlighter.setTextFragmenter(fragmenter);
//******高亮显示end******
String desc = document.get("desc");			
if(desc!=null){
						
//把全部得分高的摘要给显示出来
//第一个参数是对哪个参数进行设置;第二个是以流的方式读入
TokenStream tokenStream=analyzer.tokenStream("desc", new StringReader(desc));
//获取最高的片段
System.out.println(highlighter.getBestFragment(tokenStream, desc));
	}
}

以上的代码,就是设置高亮显示的效果,就像百度里的高亮显示一样,如下图:




评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值