Lucene学习之入门

2016-12-02 15:07

  今天开始接触Lucene搜索,Lucene是一个全文检索的框架,主要适用于搜索,这里的搜索不同于数据库的查询。Lucene是建立索引然后存在你设置的路径或者内存中,然后当你输入条件的时候就会去索引文件检索查询。Lucene能够实现分词和查询结构高亮的功能,而且在其强大的架构下全文检索的速度是比较快的。由于Lucene将数据分词后以索引方式存储,这就势必会占内存或空间(Lucene的索引存储一般有文件存储和内存存储2种方式),我们就会将不必要的东西不存储。而我们一般在使用Lucene和数据库结合的时候,像主键这些是要存的,就有利于我们在搜索的时候得到document对象同时也能得到存储在里面的主键,然后就可以通过主键获取数据库里面的数据。

  接下来开始第一个Lucene程序,首先导入lucene-core.jar的包,Lucene基本所有重要的类都在core包中。

public class Test1 {
private static Directory directory;static{
    directory = new RAMDirectory();
}public static void main(String[] args) {
    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
    IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_35, analyzer);    try {
        IndexWriter writer = new IndexWriter(directory, conf);
        Document doc = null;        for(int i=1;i<=10;i++){
            doc = new Document();
            doc.add(new Field("name", "dlm"+i, Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.add(new Field("pass", "wei dlm"+i, Field.Store.YES, Field.Index.ANALYZED));
            writer.addDocument(doc);
        }
        doc = new Document();
        doc.add(new Field("name", "sdlm", Field.Store.YES, Field.Index.NOT_ANALYZED));
        writer.addDocument(doc);
        writer.commit();
        IndexReader reader = IndexReader.open(directory);
        IndexSearcher searcher = new IndexSearcher(reader);
        TermQuery query = new TermQuery((new Term("name","dlm1")));
        TopDocs topDocs = searcher.search(query, 20);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;        for(ScoreDoc s:scoreDocs){
            Document d = searcher.doc(s.doc);
            System.out.println(s.score+"===="+d.get("name")+"--"+d.get("pass"));
        }
    searcher.close();
    reader.close();
    writer.close();
    } catch (IOException e) {        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

 

   Directory对象是指管理索引文件存储位置的对象,RAMDirectory即表示将索引存储在内存,当然程序一运行结束,索引也就不存在了。然后创建分词器Analyzer表示分词器,在这里我使用的是标准分词器StandardAnalyzer,当然不同的分词器实现的功能也不是一样的(StopAnalyzer停词分词器,WhitespaceAnalyzer空格分词器),这些所有的分词器都是不支持中文分词的。然后创建IndexWriterConfig对象以此创建IndexWriter对象,IndexWriter主要用于存储索引,所以我们传入Directory和IndexWriterConfig。Document是存放待存储内容和待创建的索引对象,Field.Store.YES就是前面提到的是否存储,一一般内容不需要存储,这里存储指储存到索引文件中,我们后面查询出来能够Document.get(name)获取到存储的值,设置NO即不能存储就不能取出值。Field.Index.ANALYZED 进行分词和索引,适用于文章标题、内容, Field.Index.NOT_ANALYZED 进行索引但是不分词,如身份证、ID,适用于精确搜索Field.Index.NOT_ANALYZED_NO_NORMS 既不分词也不存储normal信息, Field.Index.ANALYZED_NO_NORMS 分词不存储normal信息,Field.Index.NO 不分词不索引。添加完后需要提交commit,不然搜索不到索引。

   IndexReader由open(Directory)即找到索引的位置,IndexSearcher由reader获取得到,TermQuery表示精确查询,在这里输入dlm是查找不到结果的,searcher.search(query, 20);表示查找20条数据,topDocs.scoreDocs获得查询的结果集,然后遍历结果集,searcher.doc(s.doc);s.doc表示该查询结构所在的位置,然后得到document对象,就可以获得存储在索引文件中的值了。