论坛首页 综合技术论坛

lucene3.0学习笔记2-(再学Lucene的简单例子)

浏览 22979 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (6) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-01-28  
又在看Lucene,这回Lucene变成3.0了,太快了,Lucene in action 第二版也出来了
所以决定看一看

做了两个简单的例子
创建索引
package com.langhua;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
/**
 * 创建索引 Lucene 3.0+
 * @author Administrator
 *
 */
public class Indexer {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//保存索引文件的地方
		String indexDir = "F:\\indexDir";
		//将要搜索TXT文件的地方
		String dateDir = "F:\\dateDir";
		IndexWriter indexWriter = null;
		//创建Directory对象
		Directory dir = new SimpleFSDirectory(new File(indexDir));
		//创建IndexWriter对象,第一个参数是Directory,第二个是分词器,第三个表示是否是创建,如果为false为在此基础上面修改,第四表示表示分词的最大值,比如说new MaxFieldLength(2),就表示两个字一分,一般用IndexWriter.MaxFieldLength.LIMITED 
		indexWriter = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_30),true,IndexWriter.MaxFieldLength.UNLIMITED);
		File[] files = new File(dateDir).listFiles();
		for (int i = 0; i < files.length; i++) {
			Document doc = new Document();
			//创建Field对象,并放入doc对象中
			doc.add(new Field("contents", new FileReader(files[i]))); 
			doc.add(new Field("filename", files[i].getName(), 
								Field.Store.YES, Field.Index.NOT_ANALYZED));
			doc.add(new Field("indexDate",DateTools.dateToString(new Date(), DateTools.Resolution.DAY),Field.Store.YES,Field.Index.NOT_ANALYZED));
			//写入IndexWriter
			indexWriter.addDocument(doc);
		}
		//查看IndexWriter里面有多少个索引
		System.out.println("numDocs"+indexWriter.numDocs());
		indexWriter.close();
		
	}

}



搜索索引 Lucene 3.0+

package com.langhua;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.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.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
/**
 * 搜索索引 Lucene 3.0+
 * @author Administrator
 *
 */
public class Searcher {

	public static void main(String[] args) throws IOException, ParseException {
		//保存索引文件的地方
		String indexDir = "F:\\indexDir";
		Directory dir = new SimpleFSDirectory(new File(indexDir));
		//创建 IndexSearcher对象,相比IndexWriter对象,这个参数就要提供一个索引的目录就行了
		IndexSearcher indexSearch = new IndexSearcher(dir);
		//创建QueryParser对象,第一个参数表示Lucene的版本,第二个表示搜索Field的字段,第三个表示搜索使用分词器
		QueryParser queryParser = new QueryParser(Version.LUCENE_30,
				"contents", new StandardAnalyzer(Version.LUCENE_30));
		//生成Query对象
		Query query = queryParser.parse("langhua9527");
		//搜索结果 TopDocs里面有scoreDocs[]数组,里面保存着索引值
		TopDocs hits = indexSearch.search(query, 10);
		//hits.totalHits表示一共搜到多少个
		System.out.println("找到了"+hits.totalHits+"个");
		//循环hits.scoreDocs数据,并使用indexSearch.doc方法把Document还原,再拿出对应的字段的值
		for (int i = 0; i < hits.scoreDocs.length; i++) {
			ScoreDoc sdoc = hits.scoreDocs[i];
			Document doc = indexSearch.doc(sdoc.doc);
			System.out.println(doc.get("filename"));			
		}		
		indexSearch.close();
	}
}

   发表时间:2010-02-23  
3Q,例子很有用!不过我想根据文件名来索引,所以修改了一下程序,即把Searcher的:
QueryParser queryParser = new QueryParser(Version.LUCENE_30,  
                "contents", new StandardAnalyzer(Version.LUCENE_30));
修改如下:
QueryParser queryParser = new QueryParser(Version.LUCENE_30,  
                "filename", new StandardAnalyzer(Version.LUCENE_30));
即让contents换成filename。
但是却搜索不出结果,是不是这样修改还不行?
0 请登录后投票
   发表时间:2010-02-23  
MultiArrow 写道
3Q,例子很有用!不过我想根据文件名来索引,所以修改了一下程序,即把Searcher的:
QueryParser queryParser = new QueryParser(Version.LUCENE_30,  
                "contents", new StandardAnalyzer(Version.LUCENE_30));
修改如下:
QueryParser queryParser = new QueryParser(Version.LUCENE_30,  
                "filename", new StandardAnalyzer(Version.LUCENE_30));
即让contents换成filename。
但是却搜索不出结果,是不是这样修改还不行?

这样修改是可以的,但是原因是你在建立索引的时候参数不对
doc.add(new Field("filename",fileList[i].getName(),Field.Store.YES,Field.Index.ANALYZED_NO_NORMS));

Field.Index.有多个值哈。。。
0 请登录后投票
   发表时间:2010-02-24  
换成了Field.Index.ANALYZED_NO_NORMS,程序没问题了。上网查了一下:

Field.Index有五个属性,分别是:

Field.Index.ANALYZED:分词索引

Field.Index.NOT_ANALYZED:分词进行索引,如作者名,日期等,Rod Johnson本身为一单词,不再需要分词。

Field.Index.NO:不进行索引,存放不能被搜索的内容如文档的一些附加属性如文档类型, URL等。

Field.Index.NOT_ANALYZED_NO_NORMS:不使用分词索引,不使用存储规则。

Field.Index.ANALYZED_NO_NORMS:使用分词索引,不使用存储规则。

楼主能不能解释一下?
1 请登录后投票
   发表时间:2010-02-24  
晕,颜色标错了,应该是这一句:
Field.Index.ANALYZED_NO_NORMS:使用分词索引,不使用存储规则。

楼主将就着看一下
0 请登录后投票
   发表时间:2010-02-24  
还有,我为数据库的一个字段建立索引,不使用分词。将程序修改如下:
// 连接数据库
Connection conn = db.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();

// 为表字段建立索引
Directory dir = new SimpleFSDirectory(new File(indexDir));
IndexWriter indexWriter = new IndexWriter(dir,
new StandardAnalyzer(Version.LUCENE_30), true,
IndexWriter.MaxFieldLength.UNLIMITED);
while (rs.next()) {
System.out.println(rs.getString("name"));
Document doc = new Document();
[color=blue][/color]
indexWriter.addDocument(doc);
}
但是搜索不出结果,不知道是不是还是Field字段的问题?
0 请登录后投票
   发表时间:2010-02-24  
晕了,5楼的排版怎么变成了这样 ,重来:

// 连接数据库
Connection conn = db.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();

// 为表字段建立索引
Directory dir = new SimpleFSDirectory(new File(indexDir));
IndexWriter indexWriter = new IndexWriter(dir,
new StandardAnalyzer(Version.LUCENE_30), true,
IndexWriter.MaxFieldLength.UNLIMITED);
while (rs.next()) {
System.out.println(rs.getString("name"));
Document doc = new Document();
doc.add(new Field("name", rs.getString("name"),
Field.Store.YES, Field.Index.NOT_ANALYZED));
indexWriter.addDocument(doc);
}


刚学lucene,问题比较多,请楼主有时间帮一下忙,thx!
0 请登录后投票
   发表时间:2010-02-24  
// 连接数据库 
Connection conn = db.getConnection(); 
PreparedStatement stmt = conn.prepareStatement(sql); 
ResultSet rs = stmt.executeQuery(); 

// 为表字段建立索引 
Directory dir = new SimpleFSDirectory(new File(indexDir)); 
IndexWriter indexWriter = new IndexWriter(dir, 
new StandardAnalyzer(Version.LUCENE_30), true, 
IndexWriter.MaxFieldLength.UNLIMITED); 
while (rs.next()) { 
System.out.println(rs.getString("name")); 
Document doc = new Document(); 
doc.add(new Field("name", rs.getString("name"), 
Field.Store.YES, Field.Index.NOT_ANALYZED)); 
indexWriter.addDocument(doc); 
} 

你这样建立也应该是找的出来的哈
Field.Index.NOT_ANALYZED这个表示不分词,但是要建立索引。。所以搜索的时候必须搜
rs.getString("name")这个才搜的出来
你再试一下
doc.add(new Field("name", (String)rs.getString("name"),
Field.Store.YES, Field.Index.NOT_ANALYZED));
0 请登录后投票
   发表时间:2010-02-24  
这是搜索的代码(searcher):
String indexDir= "D:\\workspace\\luceneworkspace\\jspluceneIndex";
		Directory dir = new SimpleFSDirectory(new File(indexDir));
		IndexSearcher indexSearch = new IndexSearcher(dir);
		QueryParser queryParser = new QueryParser(Version.LUCENE_30, "name",
				new StandardAnalyzer(Version.LUCENE_30));
		Query query = queryParser.parse("properties");
		TopDocs hits = indexSearch.search(query, 20);
		System.out.println("一共找到" + hits.totalHits + "条");
		for (int i = 0; i < hits.scoreDocs.length; i++) {
			ScoreDoc sdoc = hits.scoreDocs[i];
			Document doc = indexSearch.doc(sdoc.doc);
			System.out.println(doc.get("name"));
		}
		indexSearch.close();

properties是表中有的,不过还是找不到结果。这个代码有什么问题吗?
0 请登录后投票
   发表时间:2010-02-24  

//System.out.println(rs.getString("name")); 

注了
或者
System.out.println(rs.getString("name")); 
System.out.println(rs.getString("name")); 

输出两次,看一下第二次取出来的值是多少

或者
doc.add(new Field("name", ((String)rs.getString("name")).trim(),   
Field.Store.YES, Field.Index.NOT_ANALYZED)); 
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics