Lucene實戰開發手記(六)--- 搜索、刪除索引代碼

本文介绍了一个基于Lucene的搜索实现案例,通过使用CJKAnalyzer进行中文分词,并结合BooleanQuery实现带有类别筛选的全文检索功能。文章详细展示了如何构建查询、执行搜索及结果高亮显示的过程。

無特別之處,了解的朋友不用看。

	
	/**
	 * 限制分類的搜索
	 * @param keyword
	 * @param categoryKeyword
	 * @return
	 * @throws LuceneException
	 */
	public  List searchIndex(String keyword, String categoryKeyword) throws LuceneException{
		Analyzer analyzer = new CJKAnalyzer();
		
		BooleanQuery query = new BooleanQuery();
		BooleanClause.Occur[] flags = new BooleanClause.Occur[]{BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD};
		try {
			Query multiQuery = MultiFieldQueryParser.parse(keyword, new String[] {
			        "topic", "contents" }, flags, analyzer);
			query.add(multiQuery, BooleanClause.Occur.MUST);
			QueryParser parse = new QueryParser("categoryId",analyzer);
			query.add(parse.parse(categoryKeyword), BooleanClause.Occur.MUST);//注意QueryParser是個很聰明的家伙,能自動判別你想要的Query的具體類型
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();			
			throw new LuceneException();
		}
		return searchIndex(query);
	}
	
	/**
	 * 搜索的實際執行方法,未做分頁
	 * @param query
	 * @return
	 * @throws LuceneException
	 */
	public  List searchIndex(Query query) throws LuceneException{
		
		List<KbIndexModel> resultList = new ArrayList<KbIndexModel>();
		File indexDir = new File(INDEX_STORE_PATH);
		Analyzer analyzer = new CJKAnalyzer();
		IndexSearcher indexSearcher;
		
		if (indexDir.exists() == false){
			return resultList;
		}
		
		try {
			indexSearcher = new IndexSearcher(IndexReader.open(indexDir));		
	        System.out.println("\nQuery:"+query.toString()+"--------------------");		

			Hits hits = indexSearcher.search(query);
			
			//高亮顯示設置
			SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(
	                "<span class=\"searchcontent\">", "</span>");
			Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));
			highlighter.setTextFragmenter(new SimpleFragmenter(CONTENTS_SHOW_LENGTH));
			
			
			for (int i = 0; i < hits.length() && i < MAX_RESULT; i++)
			{
				Document doc = hits.doc(i);
				KbIndexModel resultModel = new KbIndexModel();
				resultModel.setId(doc.get("id"));
				resultModel.setArticleId(doc.get("articleId"));
				resultModel.setFileName(doc.get("fileName"));				
				resultModel.setCategory(doc.get("category"));
				
				String topic = doc.get("topic");
				//高亮顯示
				TokenStream tokenStream = analyzer.tokenStream("topic", new StringReader(topic));
				String topic2 = highlighter.getBestFragment(tokenStream, topic);
				if (topic2 == null){
					topic2 = topic;
				}
				resultModel.setTopic(topic2);				
				//後面的代碼無關緊要
				String contents = hits.doc(i).get("contents");				
				
				tokenStream = analyzer.tokenStream("contents", new StringReader(contents));
				String contents2 = highlighter.getBestFragment(tokenStream, contents);
				
				if(contents2 == null){
					if (contents == null){
						contents2 = "";
					}
					else if (contents.length() > CONTENTS_SHOW_LENGTH){
						contents2 = contents.substring(0, CONTENTS_SHOW_LENGTH);
					}	
					else{
						contents2 = contents;
					}					
				}		
				
				resultModel.setContents(contents2 + "...");

				resultModel.setIndex(i+1);
				resultList.add(resultModel);
				indexSearcher.close();
			}		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new LuceneException();
		} 
		return resultList;
	}
	
	/*
	 * 依ID刪除索引
	 */
	public void delIndex(String id) throws LuceneException {
		IndexReader indexReader;
		try {
			File indexDir = new File(INDEX_STORE_PATH);
			if (indexDir.exists()){
				indexReader = IndexReader.open(INDEX_STORE_PATH);		
				Term term = new Term("id", id);		
				indexReader.deleteDocuments(term);
				indexReader.close();IndexWriter indexWriter = new IndexWriter(INDEX_STORE_PATH, new CJKAnalyzer(), false);
    indexWriter.optimize();
    indexWriter.close();
			}			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new LuceneException();
		}
	}
	

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值