Lucene全文搜索学习笔记(二)

个人笔记之用,如有错误,恳请批评指正。

LuceneUtil的编写,主要是对document2bean以及bean2document操作的封装。写的不完善,先学完Lucene再说。

public class LuceneUtil {
	private static Directory directory;
	private static Version version;
	private static Analyzer analyzer;
	private static MaxFieldLength maxFieldLength;
	static{
		try {
			directory = FSDirectory.open(new File("F:/java/practice/luceneDir"));
			version = Version.LUCENE_30;
			analyzer = new StandardAnalyzer(version);
			maxFieldLength = MaxFieldLength.LIMITED;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @param obj 传入的对象,用到反射将Field存入索引库
	 * @return doc对象
	 * @throws Exception
	 */
	public static Document bean2document(Object obj) throws Exception{
		/*
		 * 思路:document.add(new Field(name,content,Store?,Index?))
		 * 利用反射获取传入的obj中name属性对应的content
		 * */
		Document document = new Document();
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		//对传入的obj每个field遍历,利用get方法取出值并存入索引库
		for (Field field : fields) {
			field.setAccessible(true);
			String getMethodName = "get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
			Method method = clazz.getDeclaredMethod(getMethodName, null);
			String fieldValue = "";
			if(method.invoke(obj, null)!=null){
				fieldValue = method.invoke(obj, null).toString();//参数1:执行的对象,参数2:所需的参数
			}
			document.add(new org.apache.lucene.document.Field(field.getName(), fieldValue, Store.YES, Index.ANALYZED));//两种Field
		}
		return document;
	}
	/**
	 * 
	 * @param document
	 * @param clazz 返回的Class
	 * @return
	 * @throws Exception
	 */
	public static Object document2bean(Document document,Class clazz) throws Exception{
		/*
		 * 思路 :BeanUtils.setProperty(obj,name,value);
		 **/
		Object obj = clazz.newInstance();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			String name = field.getName();
			BeanUtils.setProperty(obj, name, document.get(name).toString());//参数1:对象. 参数2:变量名 .参数3:变量值
		}
		return obj;
	}

	public static Directory getDirectory() {
		return directory;
	}
	public static Version getVersion() {
		return version;
	}
	public static Analyzer getAnalyzer() {
		return analyzer;
	}
	public static MaxFieldLength getMaxFieldLength() {
		return maxFieldLength;
	}
}

Lucene的增删改查:

public class LuceneCRUD {
	
	
	public void addIndexDB(Object obj){
		try {
			Document document = LuceneUtil.bean2document(obj);
			IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
			indexWriter.addDocument(document);
			indexWriter.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void updateIndexDB(Object obj){
		try {
			Document document = LuceneUtil.bean2document(obj);
			IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
			//Term表示需要更新的document对象。id用户找到该document。在这里先写死。
			indexWriter.updateDocument(new Term("id","1"), document);
			indexWriter.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void deleteAllIndexDB(){
		try {
			IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
			indexWriter.deleteAll();
			indexWriter.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void deleteIndexDB(){
		try {
			IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
			indexWriter.deleteDocuments(new Term("id","1"));// 删除id为1的doc
			indexWriter.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void searchIndexDB(String keyword){
		try {
			IndexSearcher indexSearcher = new IndexSearcher(LuceneUtil.getDirectory());
			QueryParser queryParser = new QueryParser(Version.LUCENE_30, "content", LuceneUtil.getAnalyzer());
			Query query = queryParser.parse(keyword);
			TopDocs topDocs = indexSearcher.search(query, 5);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			for (ScoreDoc scoreDoc : scoreDocs) {
				Document doc = indexSearcher.doc(scoreDoc.doc);
				Article article = (Article) LuceneUtil.document2bean(doc, Article.class);
				System.out.println(article.getTitle()+":"+article.getContent());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void testAdd(){
		addIndexDB(new Article(1,"标题","内容"));
	}
	@Test
	public void testDelete(){
		deleteIndexDB();
	}
	@Test
	public void testDeleteAll(){
		deleteAllIndexDB();
	}
	@Test
	public void testSearch(){
		searchIndexDB("");
	}
	@Test
	public void testUpdate(){
		updateIndexDB(new Article(1,"新标题2","好!"));
	}
}


分页的初步实现:

public class LuceneDaoImpl {
	
	
	public List<Article> selectArticlePage(String keyword,int pageIndex,int pageSize){
		List<Article> list = new ArrayList<Article>();
		IndexSearcher indexSearcher = null;
		try {
			int start = (pageIndex-1)*pageSize;
			int end = pageIndex*pageSize;
			
			QueryParser queryParser = new QueryParser(Version.LUCENE_30,"title", LuceneUtil.getAnalyzer());
			Query query = queryParser.parse(keyword);
			indexSearcher = new IndexSearcher(LuceneUtil.getDirectory());
			TopDocs topDocs = indexSearcher.search(query, end);
			System.out.println("总记录数为:"+topDocs.totalHits);
			
			//总记录数小于end,说明scoreDocs不满end条。即返回的是start--totalHits条。否则返回的是start--end条
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			int size = end;
			if(topDocs.totalHits<end) {
				size = topDocs.totalHits;
			}
			if(topDocs.totalHits<=start){
				System.out.println("没有记录了!");
				return null;
			}
			for(int i = start ;i<size;i++){
				Document doc = indexSearcher.doc(scoreDocs[i].doc);
				Article article = (Article) LuceneUtil.document2bean(doc,Article.class);
				list.add(article);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				indexSearcher.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
			return list;
	}
	@Test
	public void testSearchPage(){
		int pageIndex = 1;
		int pageSize = 19;
		List<Article> list = selectArticlePage("标题", pageIndex, pageSize);
		if(list!=null){
			System.out.println(list.size());
			for (Article article : list) {
				System.out.println(article.getTitle()+":"+article.getContent());
			}
			System.out.println("第"+pageIndex+"页"+"每页"+pageSize+"条");
			}
		}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值