我用lucene实现搜索,现在处于最基础的阶段,即只是实现对文档内容的搜索,返回结果数。
建立索引程序代码如下:
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:\\testroomtxt\\index";
//将要搜索TXT文件的地方
String dateDir = "F:\\testroomtxt\\testroom";
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.LIMITED);
File[] files = new File(dateDir).listFiles(); //返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
for (int i = 0; i < files.length; i++) {
//建立一个document对象,Document,相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。
Document doc = new Document();
//创建Field对象,并放入doc对象中,一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。
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 com.langhua;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;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:\\testroomtxt\\index";
Directory dir = new SimpleFSDirectory(new File(indexDir));
//创建 IndexSearcher对象,相比IndexWriter对象,这个参数就要提供一个索引的目录就行了
IndexSearcher indexSearch = new IndexSearcher(dir);
String queries = null;
BufferedReader in = null;
if (queries != null) {
in = new BufferedReader(new FileReader(queries));
} else {
in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
}
QueryParser parser = new QueryParser(Version.LUCENE_30, "contents", new StandardAnalyzer(Version.LUCENE_30));
Query query = null;
while (true) {
if (queries == null) // prompt the user
System.out.println("Enter query: "); String line = in.readLine(); if (line == null || line.length() == -1)
break; line = line.trim();
if (line.length() == 0)
break;
query = parser.parse(line);
System.out.println("Searching for: " + query.toString("contents"));
//搜索结果 TopDocs里面有scoreDocs[]数组,里面保存着索引值,找前10个
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"));
System.out.println(doc.get("contents"));
}
}
indexSearch.close();
}
}最后这边返回文档对应字段的值的时候System.out.println(doc.get("contents"));这个语句,执行结果一直是null,到底应该怎么返回文档搜索字段的值呢??急求答案,希望大侠们能解救一下,感激不尽。
建立索引程序代码如下:
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:\\testroomtxt\\index";
//将要搜索TXT文件的地方
String dateDir = "F:\\testroomtxt\\testroom";
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.LIMITED);
File[] files = new File(dateDir).listFiles(); //返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
for (int i = 0; i < files.length; i++) {
//建立一个document对象,Document,相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。
Document doc = new Document();
//创建Field对象,并放入doc对象中,一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。
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 com.langhua;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;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:\\testroomtxt\\index";
Directory dir = new SimpleFSDirectory(new File(indexDir));
//创建 IndexSearcher对象,相比IndexWriter对象,这个参数就要提供一个索引的目录就行了
IndexSearcher indexSearch = new IndexSearcher(dir);
String queries = null;
BufferedReader in = null;
if (queries != null) {
in = new BufferedReader(new FileReader(queries));
} else {
in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
}
QueryParser parser = new QueryParser(Version.LUCENE_30, "contents", new StandardAnalyzer(Version.LUCENE_30));
Query query = null;
while (true) {
if (queries == null) // prompt the user
System.out.println("Enter query: "); String line = in.readLine(); if (line == null || line.length() == -1)
break; line = line.trim();
if (line.length() == 0)
break;
query = parser.parse(line);
System.out.println("Searching for: " + query.toString("contents"));
//搜索结果 TopDocs里面有scoreDocs[]数组,里面保存着索引值,找前10个
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"));
System.out.println(doc.get("contents"));
}
}
indexSearch.close();
}
}最后这边返回文档对应字段的值的时候System.out.println(doc.get("contents"));这个语句,执行结果一直是null,到底应该怎么返回文档搜索字段的值呢??急求答案,希望大侠们能解救一下,感激不尽。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货