原创作者: likunkun
阅读:2046次
评论:0条
更新时间:2011-05-26
接http://www.iteye.com/post/190335
到现在我们已经可以用lucene建立索引了
下面介绍一下几个功能来完善一下:
1.索引格式
其实索引目录有两种格式,一种是除配置文件外,每一个Document独立成为一个文件(这种搜索起来会影响速度)。另一种是全部的Document成一个文件,这样属于复合模式就快了。
2.索引文件可放的位置:
索引可以存放在两个地方1.硬盘,2.内存
放在硬盘上可以用FSDirectory(),放在内存的用RAMDirectory()不过一关机就没了
FSDirectory.getDirectory(File file, boolean create)
FSDirectory.getDirectory(String path, boolean create)两个工厂方法返回目录
New RAMDirectory()就直接可以
再和IndexWriter(Directory d, Analyzer a, boolean create)一配合就行了
如:
IndexWrtier indexWriter = new IndexWriter(FSDirectory.getDirectory(“c:\\index”,true),new StandardAnlyazer(),true);
IndexWrtier indexWriter = new IndexWriter(new RAMDirectory(),new StandardAnlyazer(),true);
3.索引的合并
这个可用IndexWriter.addIndexes(Directory[] dirs)将目录加进去
来看个例子:
[code]
public void UniteIndex() throws IOException
{
IndexWriter writerDisk = new IndexWriter(FSDirectory.getDirectory("c:\\indexDisk", true),new StandardAnalyzer(),true);
Document docDisk = new Document();
docDisk.add(new Field("name","程序员之家",Field.Store.YES,Field.Index.TOKENIZED));
writerDisk.addDocument(docDisk);
RAMDirectory ramDir = new RAMDirectory();
IndexWriter writerRam = new IndexWriter(ramDir,new StandardAnalyzer(),true);
Document docRam = new Document();
docRam.add(new Field("name","程序员杂志",Field.Store.YES,Field.Index.TOKENIZED));
writerRam.addDocument(docRam);
writerRam.close();//这个方法非常重要,是必须调用的
writerDisk.addIndexes(new Directory[]{ramDir});
writerDisk.close();
}
public void UniteSearch() throws ParseException, IOException
{
QueryParser queryParser = new QueryParser("name",new StandardAnalyzer());
Query query = queryParser.parse("程序员");
IndexSearcher indexSearcher =new IndexSearcher("c:\\indexDisk");
Hits hits = indexSearcher.search(query);
System.out.println("找到了"+hits.length()+"结果");
for(int i=0;i
{
Document doc = hits.doc(i);
System.out.println(doc.get("name"));
}
}
[/code]
这个例子是将内存中的索引合并到硬盘上来.
注意:合并的时候一定要将被合并的那一方的IndexWriter的close()方法调用。
4.对索引的其它操作:
IndexReader类是用来操作索引的,它有对Document,Field的删除等操作。
下面一部分的内容是:全文的搜索
全文的搜索主要是用:IndexSearcher,Query,Hits,Document(都是Query的子类),有的时候用QueryParser
主要步骤:
1.new QueryParser(Field字段,new 分析器)
2.Query query = QueryParser.parser(“要查询的字串”);这个地方我们可以用反射api看一下query究竟是什么类型
3.new IndexSearcher(索引目录).search(query);返回Hits
4.用Hits.doc(n);可以遍历出Document
5.用Document可得到Field的具体信息了。
其实1 ,2两步就是为了弄出个Query 实例,究竟是什么类型的看分析器了。
拿以前的例子来说吧
QueryParser queryParser = new QueryParser("name",new StandardAnalyzer());
Query query = queryParser.parse("程序员");
/*这里返回的就是org.apache.lucene.search.PhraseQuery*/
IndexSearcher indexSearcher =new IndexSearcher("c:\\indexDisk");
Hits hits = indexSearcher.search(query);
不管是什么类型,无非返回的就是Query的子类,我们完全可以不用这两步直接new个Query的子类的实例就ok了,不过一般还是用这两步因为它返回的是PhraseQuery这个是非常强大的query子类它可以进行多字搜索用QueryParser可以设置各个关键字之间的关系这个是最常用的了。
IndexSearcher:
其实IndexSearcher它内部自带了一个IndexReader用来读取索引的,IndexSearcher有个close()方法,这个方法不是用来关闭IndexSearche的是用来关闭自带的IndexReader。
QueryParser呢可以用parser.setOperator()来设置各个关键字之间的关系(与还是或)它可以自动通过空格从字串里面将关键字分离出来。
注意:用QueryParser搜索的时候分析器一定的和建立索引时候用的分析器是一样的。
Query:
可以看一个lucene2.0的帮助文档有很多的子类:
BooleanQuery, ConstantScoreQuery, ConstantScoreRangeQuery, DisjunctionMaxQuery, FilteredQuery, MatchAllDocsQuery, MultiPhraseQuery, MultiTermQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery
各自有用法看一下文档就能知道它们的用法了
下面一部分讲一下lucene的分析器:
分析器是由分词器和过滤器组成的,拿英文来说吧分词器就是通过空格把单词分开,过滤器就是把the,to,of等词去掉不被搜索和索引。
我们最常用的是StandardAnalyzer()它是lucene的标准分析器它集成了内部的许多的分析器。
最后一部分了:lucene的高级搜索了
1.排序
Lucene有内置的排序用IndexSearcher.search(query,sort)但是功能并不理想。我们需要自己实现自定义的排序。
这样的话得实现两个接口: ScoreDocComparator, SortComparatorSource
用IndexSearcher.search(query,new Sort(new SortField(String Field,SortComparatorSource)));
就看个例子吧:
这是一个建立索引的例子:
[code]
public void IndexSort() throws IOException
{
IndexWriter writer = new IndexWriter("C:\\indexStore",new StandardAnalyzer(),true);
Document doc = new Document()
doc.add(new Field("sort","1",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","4",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","3",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","5",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","9",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","6",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","7",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
writer.close();
}
[/code]
(未完)
到现在我们已经可以用lucene建立索引了
下面介绍一下几个功能来完善一下:
1.索引格式
其实索引目录有两种格式,一种是除配置文件外,每一个Document独立成为一个文件(这种搜索起来会影响速度)。另一种是全部的Document成一个文件,这样属于复合模式就快了。
2.索引文件可放的位置:
索引可以存放在两个地方1.硬盘,2.内存
放在硬盘上可以用FSDirectory(),放在内存的用RAMDirectory()不过一关机就没了
FSDirectory.getDirectory(File file, boolean create)
FSDirectory.getDirectory(String path, boolean create)两个工厂方法返回目录
New RAMDirectory()就直接可以
再和IndexWriter(Directory d, Analyzer a, boolean create)一配合就行了
如:
IndexWrtier indexWriter = new IndexWriter(FSDirectory.getDirectory(“c:\\index”,true),new StandardAnlyazer(),true);
IndexWrtier indexWriter = new IndexWriter(new RAMDirectory(),new StandardAnlyazer(),true);
3.索引的合并
这个可用IndexWriter.addIndexes(Directory[] dirs)将目录加进去
来看个例子:
[code]
public void UniteIndex() throws IOException
{
IndexWriter writerDisk = new IndexWriter(FSDirectory.getDirectory("c:\\indexDisk", true),new StandardAnalyzer(),true);
Document docDisk = new Document();
docDisk.add(new Field("name","程序员之家",Field.Store.YES,Field.Index.TOKENIZED));
writerDisk.addDocument(docDisk);
RAMDirectory ramDir = new RAMDirectory();
IndexWriter writerRam = new IndexWriter(ramDir,new StandardAnalyzer(),true);
Document docRam = new Document();
docRam.add(new Field("name","程序员杂志",Field.Store.YES,Field.Index.TOKENIZED));
writerRam.addDocument(docRam);
writerRam.close();//这个方法非常重要,是必须调用的
writerDisk.addIndexes(new Directory[]{ramDir});
writerDisk.close();
}
public void UniteSearch() throws ParseException, IOException
{
QueryParser queryParser = new QueryParser("name",new StandardAnalyzer());
Query query = queryParser.parse("程序员");
IndexSearcher indexSearcher =new IndexSearcher("c:\\indexDisk");
Hits hits = indexSearcher.search(query);
System.out.println("找到了"+hits.length()+"结果");
for(int i=0;i
{
Document doc = hits.doc(i);
System.out.println(doc.get("name"));
}
}
[/code]
这个例子是将内存中的索引合并到硬盘上来.
注意:合并的时候一定要将被合并的那一方的IndexWriter的close()方法调用。
4.对索引的其它操作:
IndexReader类是用来操作索引的,它有对Document,Field的删除等操作。
下面一部分的内容是:全文的搜索
全文的搜索主要是用:IndexSearcher,Query,Hits,Document(都是Query的子类),有的时候用QueryParser
主要步骤:
1.new QueryParser(Field字段,new 分析器)
2.Query query = QueryParser.parser(“要查询的字串”);这个地方我们可以用反射api看一下query究竟是什么类型
3.new IndexSearcher(索引目录).search(query);返回Hits
4.用Hits.doc(n);可以遍历出Document
5.用Document可得到Field的具体信息了。
其实1 ,2两步就是为了弄出个Query 实例,究竟是什么类型的看分析器了。
拿以前的例子来说吧
QueryParser queryParser = new QueryParser("name",new StandardAnalyzer());
Query query = queryParser.parse("程序员");
/*这里返回的就是org.apache.lucene.search.PhraseQuery*/
IndexSearcher indexSearcher =new IndexSearcher("c:\\indexDisk");
Hits hits = indexSearcher.search(query);
不管是什么类型,无非返回的就是Query的子类,我们完全可以不用这两步直接new个Query的子类的实例就ok了,不过一般还是用这两步因为它返回的是PhraseQuery这个是非常强大的query子类它可以进行多字搜索用QueryParser可以设置各个关键字之间的关系这个是最常用的了。
IndexSearcher:
其实IndexSearcher它内部自带了一个IndexReader用来读取索引的,IndexSearcher有个close()方法,这个方法不是用来关闭IndexSearche的是用来关闭自带的IndexReader。
QueryParser呢可以用parser.setOperator()来设置各个关键字之间的关系(与还是或)它可以自动通过空格从字串里面将关键字分离出来。
注意:用QueryParser搜索的时候分析器一定的和建立索引时候用的分析器是一样的。
Query:
可以看一个lucene2.0的帮助文档有很多的子类:
BooleanQuery, ConstantScoreQuery, ConstantScoreRangeQuery, DisjunctionMaxQuery, FilteredQuery, MatchAllDocsQuery, MultiPhraseQuery, MultiTermQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery
各自有用法看一下文档就能知道它们的用法了
下面一部分讲一下lucene的分析器:
分析器是由分词器和过滤器组成的,拿英文来说吧分词器就是通过空格把单词分开,过滤器就是把the,to,of等词去掉不被搜索和索引。
我们最常用的是StandardAnalyzer()它是lucene的标准分析器它集成了内部的许多的分析器。
最后一部分了:lucene的高级搜索了
1.排序
Lucene有内置的排序用IndexSearcher.search(query,sort)但是功能并不理想。我们需要自己实现自定义的排序。
这样的话得实现两个接口: ScoreDocComparator, SortComparatorSource
用IndexSearcher.search(query,new Sort(new SortField(String Field,SortComparatorSource)));
就看个例子吧:
这是一个建立索引的例子:
[code]
public void IndexSort() throws IOException
{
IndexWriter writer = new IndexWriter("C:\\indexStore",new StandardAnalyzer(),true);
Document doc = new Document()
doc.add(new Field("sort","1",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","4",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","3",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","5",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","9",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","6",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
doc = new Document();
doc.add(new Field("sort","7",Field.Store.YES,Field.Index.TOKENIZED));
writer.addDocument(doc);
writer.close();
}
[/code]
(未完)
评论 共 0 条 请登录后发表评论