论坛首页 综合技术论坛

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

浏览 22867 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (6) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-02-24  
langhua9527 写道

//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)); 

照做了,依然找不到结果。
补充一下:我的表里只有一个name字段,搜索的"properties"是字段的一个值。
0 请登录后投票
   发表时间:2010-02-24  
照做了,依然找不到结果。
补充一下:我的表里只有一个name字段,搜索的"properties"是字段的一个值。
0 请登录后投票
   发表时间:2010-02-24   最后修改:2010-02-24
上述问题,仅从表象上来说应该是在添加完Document后,IndexWriter没有commit或者close,致使添加的文档不能够被打开的IndexReader或IndexSearcher看到,所以不能够搜索出来。

我做了以下程序,也是当IndexWriter.commit调用则搜的出来,否则搜不出来,代码如下:

    String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    String url = "jdbc:derby:";
    Class.forName(driver).newInstance();
    Connection connection = DriverManager.getConnection(url+"TestIndexDatabaseField/Database;create=true");
    Statement createstmt = connection.createStatement();
    String dbcreatesql = "CREATE TABLE TestIndexDatabaseField (name VARCHAR(50) PRIMARY KEY)";
    createstmt.executeUpdate(dbcreatesql);
    createstmt.close();

    String insertsql = "INSERT INTO TestIndexDatabaseField (name) " + "VALUES(?)";
    PreparedStatement stmt = connection.prepareStatement(insertsql);
    stmt.setString(1, "properties");
    stmt.executeUpdate();
    stmt.close();

    String selectsql = "SELECT name FROM TestIndexDatabaseField";
    stmt = connection.prepareStatement(selectsql);
    ResultSet rs = stmt.executeQuery();
    File indexDir = new File("TestIndexDatabaseField/Index");
    IndexWriter writer = new IndexWriter(FSDirectory.open(indexDir), new StandardAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);

    while (rs.next()) {
      String name = rs.getString("name");
      Document doc = new Document();
      doc.add(new Field("name", name, Field.Store.YES, Field.Index.NOT_ANALYZED));
      writer.addDocument(doc);
    }

    rs.close();
    stmt.close();
    //commit is here
    writer.commit();
    
    IndexSearcher searcher = new IndexSearcher(FSDirectory.open(indexDir));
    QueryParser parser = new QueryParser(Version.LUCENE_30, "name", new StandardAnalyzer(Version.LUCENE_30));
    Query query = parser.parse("properties");
    TopDocs docs = searcher.search(query, 10);
    for (ScoreDoc doc : docs.scoreDocs) {
      System.out.println("docid : " + doc.doc + " score : " + doc.score);
      Document ldoc = searcher.doc(doc.doc);
      System.out.println(ldoc.get("name"));
    }
    searcher.close();
    
    writer.close();


这是Lucene对类似数据库的事务的支持:
1.IndexWriter添加文档后,如果不commit,则不能被新打开的IndexReader看到从上次commit至今的文档。
2.IndexReader一旦打开,相当于对当前的索引建立了一个snapshot,仅能看到此时间之前commit过的文档,除非此IndexReader重新打开,否则即便IndexWriter添加了文档,并且commit了,也不能够被搜到。
3.为了支持实时索引搜索,Lucene 3.0提供了IndexWriter.getReader方法,使得不commit的文档也能够被看到。
在上述代码中注释掉writer.commit()函数,然而创建IndexSearcher的时候应用以下代码,则也能够搜的出来。
    //writer.commit();
    IndexSearcher searcher = new IndexSearcher(writer.getReader());


不知道是否回答了您的问题,欢迎讨论
0 请登录后投票
   发表时间:2010-02-24  
谢谢,非常感谢。。。。明天上班看你的文章哈。。。。
0 请登录后投票
   发表时间:2010-02-25  
问题解决了,谢谢楼上两位,俺就是看你们的文章入门的。
0 请登录后投票
   发表时间:2010-02-25  
对于以下代码:
//writer.commit();   
IndexSearcher searcher = new IndexSearcher(writer.getReader());

感觉用处不大,因为如果writer和searcher在同一个类的话还好,如果不在同一个类,searcher中调用writer应该会导致很多问题。
0 请登录后投票
   发表时间:2010-04-26  
如果用了 Field.Index.NOT_ANALYZED的话就不能用QueryParser 了,QueryParser 只查分词索引,所以查询因该写成
Query query = new TermQuery(new Term("filename", name1));
TopDocs hits = indexSearch.search(query, 20);
       
0 请登录后投票
   发表时间:2010-06-28  
多谢楼主的入门例子,和1978关于lucene的一系列文章。

都是好人。
0 请登录后投票
   发表时间:2010-07-15  
楼主,我根据你的代码,运行后英文可以正确检索出,但中文不行,将分词换成IKAnalyzer也只能检索英文,不能检索中文,原因出在哪儿哦?
0 请登录后投票
   发表时间:2010-07-15  
chudu 写道
楼主,我根据你的代码,运行后英文可以正确检索出,但中文不行,将分词换成IKAnalyzer也只能检索英文,不能检索中文,原因出在哪儿哦?

贴代码,求解决:
package org.lucene.mytest;

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;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class IndexTest {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// 保存索引文件的地方
		String indexDir = "D:\\study\\lucene\\index";
		// 将要搜索TXT文件的地方
		String dateDir = "D:\\study\\lucene\\data";
		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 IKAnalyzer(), 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();

	}

}


package org.lucene.mytest;

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

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;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class SearchTest {
	public static void main(String[] args) throws IOException, ParseException {
		// 保存索引文件的地方
		String indexDir = "D:\\study\\lucene\\index";
		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 IKAnalyzer());
		// 生成Query对象
		Query query = queryParser.parse("重要的生活星球");
		// Query query=new TermQuery(new Term("contents","重要的生活星球"));
		// 搜索结果 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();
	}
}

0 请登录后投票
论坛首页 综合技术版

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