待烦引的对象可以来自文g、数据库{Q意途径Q用戯行编码遍历目录读取文件或者查询数据库表取得ResultSetQLucene的API只负责和字符串打交道?br>1.1 Field 的解?br>
从源代码中,可以看出Field 构造函数如下:
Field(String name, byte[] value, Field.Store store)
Field(String name, Reader reader)
Field(String name, Reader reader, Field.TermVector termVector)
Field(String name, String value, Field.Store store, Field.Index index)
Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector)
在Field当中有三个内部类QField.Index,Field.Store,Field.termVector。其?br>
* Field.Index有四个属性,分别是:
Field.Index.TOKENIZEDQ分词烦?br>Field.Index.UN_TOKENIZEDQ分词进行烦引,如作者名Q日期等QRod Johnson本nZ单词Q不再需要分词?br>Field.IndexQ不q行索引Q存放不能被搜烦的内容如文档的一些附加属性如文档cd, URL{?br>Field.Index.NO_NORMSQ;
* Field.Store也有三个属性,分别是:
Field.Store.YESQ烦引文件本来只存储索引数据, 此设计将原文内容直接也存储在索引文g中,如文档的标题?br>Field.Store.NOQ原文不存储在烦引文件中Q搜索结果命中后Q再Ҏ其他附加属性如文g的PathQ数据库的主键等Q重新连接打开原文Q适合原文内容较大的情c?br>Field.Store.COMPRESS 压羃存储Q?br>* termVector是Lucene 1.4.3新增的它提供一U向量机制来q行模糊查询,很少用?br>
上面所说的Field属性与lucene1.4.3版本的有比较大的不同Q在旧版?.4.3里lucene是通过Field.Keyword (...),FieldUnIndexed(...),FieldUnstored(...)和Field.Text(...)来设|不同字D늚cd以达 C同的用途,而当前版本由Field.Index和Field.Store两个字段的不同组合来辑ֈ上述效果?br>q有一点说?其中的两个构造函数其默认的gؓField.Store.NO和Field.Index.TOKENIZED。:
Field(String name, Reader reader)
Field(String name, Reader reader, Field.TermVector termVector)
* 限制Field的长?
IndexWritercL供了一个setMaxFieldLength的方法来对Field的长度进行限Ӟ看一下源代码q道其默认gؓ10000Q?我们可以在用时重新讄此参数。如果用默认|那么Lucene׃仅对文档的前面的10000个termq行索引Q超q这一个数的文档就不会被徏?索引?br>
1.2 索引的合q、删除、优?br>
* IndexWriter中的addIndexesҎ烦引进行合q?当在不同的地方创Z索引后,如果需要将索引合ƈQ这时候用addIndexesҎ显得很有意义?br>* 可以通过IndexReadercM索引中进行文档的删除。IndexReader是很特别的一个类Q看源代码就知道它主要是通过自n的静态方法来完成构造的。示例:
IndexReader reader = IndexReader.open("C:\\springside");
reader.deleteDocument(X); //q里的X是一个int的常敎ͼ不推荐这一U删除方?br>reader.deleteDocument(new Term("name","springside"));//q是另一U删除烦引的ҎQ按字段来删除,推荐使用q一U做?br>reader.close();
* 优化索引:可以使用IndexWritercȝoptimizeҎ来进行优先,它会多个Segmentq行合ƈQ组成一个新的Segment,可以?快徏立烦引后搜烦的速度。另外需要注意的一点,optimizeҎ会降低徏立烦引的速度Q而且要求的磁盘空间会增加?br>
2. q行搜烦时最常用的几个术?br>
* IndexSearcher:是lucene中最基本的检索工P所有的索都会用到IndexSearcher工具。初始化IndexSearcher需要设|烦引存攄路径Q让查询器能定位索引而进行搜索?br>* Query:查询Qlucene中支持模p查询,语义查询Q短语查询,l合查询{等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery{一些类?br>* QueryParser: 是一个解析用戯入的工具Q可以通过扫描用户输入的字W串Q生成Query对象?br>* Hits:在搜索完成之后,需要把搜烦l果q回q显C给用户Q只有这h是完成搜烦的目的。在lucene中,搜烦的结果的集合是用Hitscȝ实例来表C的。Hits对象中主要方法有Q?br>
length(): q回搜烦l果的L,下面单的用法中有用到Hit的这一个方?br>doc(int n): q回Wn个文?br>iterator(): q回一个P代器
q里再提一下HitsQ这也是Lucene比较_ֽ的地方,熟悉hibernate的朋友都知道hibernate有一个gq加载的属性,同样, Lucene也有。Hits对象也是采用延迟加蝲的方式返回结果的Q当要访问某个文档时QHits对象在内部对Lucene的烦引又q行一ơ检索,最?才将l果q回到页面显C?br>
3. 一个简单的实例Q?br>
首先把lucene的包攑֜classpath路径中去Q写下面一个简单的c:
public class FSDirectoryTest {
//建立索引的\?br>public static final String path = "c:\\index2";
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add( new Field("name", "lighter springside com",Field.Store.YES,Field.Index.TOKENIZED));
Document doc2 = new Document();
doc2.add(new Field("name", "lighter blog",Field.Store.YES,Field.Index.TOKENIZED));
IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);
writer.addDocument(doc1);
writer.addDocument(doc2);
writer.close();
IndexSearcher searcher = new IndexSearcher(path);
Hits hits = null;
Query query = null;
QueryParser qp = new QueryParser("name",new StandardAnalyzer());
query = qp.parse("lighter");
hits = searcher.search(query);
System.out.println("查找\"lighter\" ? + hits.length() + "个结?);
query = qp.parse("springside");
hits = searcher.search(query);
System.out.println("查找\"springside\" ? + hits.length() + "个结?);
}
}
执行的结果:
查找"lighter" ?个结?br>查找"springside" ?个结?br>
4. 一个复杂一点的实例
* 在windowspȝ下的的C盘,Z个名叫s的文件夹,在该文g多w面随便徏三个txt文gQ随便v名啦Q就?1.txt","2.txt"?3.txt"?br>其中1.txt的内容如下:
springsideC
更大q步Q吸引更多用?更多贡献
2007q?br>
?2.txt"?3.txt"的内容也可以随便写几写,q里懒写Q就复制一个和1.txt文g的内容一样吧
* 下蝲lucene包,攑֜classpath路径中,然后建立索引:
/**
* author lighter date 2006-8-7
*/
public class LuceneExample {
public static void main(String[] args) throws Exception {
File fileDir = new File("c:\\s"); // 指明要烦引文件夹的位|?q里是C盘的S文g夹下
File indexDir = new File("c:\\index"); // q里攄引文件的位置
File[] textFiles = fileDir.listFiles();
Analyzer luceneAnalyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
indexFile(luceneAnalyzer,indexWriter, textFiles);
indexWriter.optimize();//optimize()Ҏ是对索引q行优化
indexWriter.close();
}
public static void indexFile(Analyzer luceneAnalyzer,IndexWriter indexWriter,File[] textFiles) throws Exception
{
//增加document到烦引去
for (int i = 0; i < textFiles.length; i++) {
if (textFiles[i].isFile() && textFiles[i].getName().endsWith(".txt")) {
String temp = FileReaderAll(textFiles[i].getCanonicalPath(),"GBK");
Document document = new Document();
Field FieldBody = new Field("body", temp, Field.Store.YES,Field.Index.TOKENIZED);
document.add(FieldBody);
indexWriter.addDocument(document);
}
}
}
public static String FileReaderAll(String FileName, String charset)throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(FileName), charset));
String line = "";
String temp = "";
while ((line = reader.readLine()) != null) {
temp += line;
}
reader.close();
return temp;
}
}
* 执行查询Q?br>
public class TestQuery {
public static void main(String[] args) throws IOException, ParseException {
Hits hits = null;
String queryString = "C";
Query query = null;
IndexSearcher searcher = new IndexSearcher("c:\\index");
Analyzer analyzer = new StandardAnalyzer();
try {
QueryParser qp = new QueryParser("body", analyzer);
query = qp.parse(queryString);
} catch (ParseException e) {
}
if (searcher != null) {
hits = searcher.search(query);
if (hits.length() > 0) {
System.out.println("扑ֈ:" + hits.length() + " 个结?");
}
}
}
}
* 执行l果Q?br>扑ֈ:3 个结?