• Lucene入门——基础知识


    Lucene简介

        Lucene是一个基于Java的全文信息检索工具包,为应用程序提供索引和搜索功能。
        Lucene采用的是一种称为反向索引(inverted index)的机制。反向索引就是说我们维护一个词/短语表,对于这个词/短语表再通过一个链表标示哪些文档包含了这个词、短语。这样在用户输入查询条件的时候,就能非常快的查找到搜索结果。对文档建好索引后,可以基于索引进行搜索。搜索引擎首先会对搜索的关键词进行解析,然后再在建立好的索引上查找,最终返回和用户输入的关键词相关联的文档。

    Lucene软件包分析

        五种基本包:
        Package: org.apache.lucene.document
        这个包提供了一些为封装要索引的文档所需要的类,比如Document,Field。这样,每一个文档最终被封装成了一个Document对象。
        Package: org.apache.lucene.analysis
        这个包主要功能是对文档进行分词,因为文档在建立索引之前必须要进行分词,所以这个包的作用可以看成是为建立索引做准备工作。
        Package: org.apache.lucene.index
        这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。这里面有两个基础的类:IndexWriter和IndexReader,其中IndexWriter是用来创建索引并添加文档到索引中的,IndexReader是用来删除索引中的文档的。
        Package: org.apache.lucene.search
        这个包提供了对在建立好的索引上进行搜索所需要的类。比如IndexSearcher和Hits,IndexSearcher定义了在指定的索引上进行搜索的方法,Hits用来保存搜索得到的结果。
        五种基本类简介:
    1. Document: Documentg是用来描述文档的,这里的文档可以指一个HTML页面,一封电子邮件,或一个文本文件。一个Document存在多个fields,每一个field有一个名字和文本类容。
    2. Field:Field对象用来面试文档的属性,含有一个名字和内容。比如电子邮件的标题,就存在标题和对应的标题内容。
    3. Analyzer:   分词处理。一个文档在被索引前,都需要进行分词处理。分词处理比较复杂的要属中文的分词处理,不过现在都有比较成熟的框架来完成。
    4. IndexWriter:IndexWriter是Lucene用来创建索引的核心类,用于将Document对象加入到内存中。
    5. Directory:代表Lucene的索引存储的位置,这是一个抽象类。 FSDirectory,表示存储在文件系统的索引位置。RAMDirectory表示一个存储在内存中的索引的位置。

    建立文本索引例子

        本例子基于Lucene代码版本为:4.10.4。所以部分代码可能与原文不一致。
    package test;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field.Store;
    import org.apache.lucene.document.TextField;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.index.IndexWriterConfig;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.apache.lucene.util.Version;
    /**
     * 文本文件建立索引
     * 
     * @author jing
     *
     */
    public class TxtFileIndexer {
        private static final String DATA_DIR = "E:\luceneData";// 数据存储位置
        private static final String INDEX_DIR = "E:\luceneIndex";// 索引文件位置
        private static Directory diskDir;// 索引存储位置
        // 加载索引Directory
        static {
            try {
                diskDir = FSDirectory.open(new File(INDEX_DIR));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args) throws IOException {
            // 数据存储位置
            File dataDir = new File(DATA_DIR);
            // 分词器
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            File[] dataFiles = dataDir.listFiles();
            // 索引
            IndexWriter indexWriter = new IndexWriter(diskDir, new IndexWriterConfig(Version.LATEST,
                    luceneAnalyzer));
            long startTime = System.currentTimeMillis();
            for (File dataFile : dataFiles) {
                if (dataFile.isFile() && dataFile.getName().endsWith(".txt")) {
                    System.out.println("分词器分词,文件: " + dataFile.getName());
                    Document document = new Document();
                    Reader txtReader = new FileReader(dataFile);
                    document.add(new TextField("path", dataFile.getCanonicalPath(), Store.YES));
                    //读取文件内容
                    char[] ch = new char[10240];
                    while( txtReader.read(ch) != -1){
                        
                        continue;
                    }
                    document.add(new TextField("contents", String.valueOf(ch), Store.YES));
                    indexWriter.addDocument(document);
                    txtReader.close();
                }
            }
            indexWriter.close();
            long endTime = System.currentTimeMillis();
            System.out.println("It takes " + (endTime - startTime)
                    + " milliseconds to create index for the files in directory " + dataDir.getPath());
        }
    }
    输出结果:
        分词器分词,文件:1-副本(2).txt
        分词器分词,文件:1-副本(3).txt
        分词器分词,文件:1-副本(4).txt
        分词器分词,文件:1-副本(5).txt
        分词器分词,文件:1-副本(6).txt
        分词器分词,文件:1-副本.txt
        分词器分词,文件:1.txt
        It takes 375 milliseconds to create index for the files in directory E:luceneData

    搜索文档类分析

    1. Query:抽象类,将用户输入的字符串分装为特定的对象。
    2. Term:搜索的基本单位,一个Term对象有两个String类型的域组成。一个参数代表文档File,一个参数表示查询的关键字。
    3. TermQuery:Query的子类,同时是Lucene支持的最基本的查询类。
    4. IndexSearch:在建立好的索引上进行搜索。只能以只读的方式打开索引。
    5. Hits:保存搜索结果。本人使用的API已经更改,使用ScoreDoc来保存。

    搜索实例

        
    package test;
    import java.io.File;
    import java.io.IOException;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.index.DirectoryReader;
    import org.apache.lucene.index.Term;
    import org.apache.lucene.search.IndexSearcher;
    import org.apache.lucene.search.ScoreDoc;
    import org.apache.lucene.search.TermQuery;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    public class TxtFileSearch {
        
        private static final String INDEX_DIR = "E:\luceneIndex";// 索引文件位置
        
        private static Directory diskDir;// 索引存储位置
        
     // 加载索引Directory
        static {
            try {
                diskDir = FSDirectory.open(new File(INDEX_DIR));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args) throws IOException {
            
            IndexSearcher searcher  = new IndexSearcher(DirectoryReader.open(diskDir));
            Term term = new Term("contents", "searcher");
            TermQuery luceneQuery = new TermQuery(term); 
            
            //Finds the top n hits for query
            ScoreDoc[] hitsAfter = searcher.search(luceneQuery, 500).scoreDocs;
            for(ScoreDoc sDoc : hitsAfter){ 
                    
                Document hitDoc = searcher.doc(sDoc.doc);
                System.out.println(hitDoc.get("path"));
            } 
        }
    }

    总结

        其中,因为api版本问题,本文对部分代码进行了修改。
        本文演示了一个基本的Lucene操作,可以认为是一个基本的入门程序。
    欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
    [CSDN博客:http://blog.csdn.net/mergades]。
    如相关博文涉及到版权问题,请联系本人。
  • 相关阅读:
    Membership角色与权限管理
    Virtual PC 2007 下载地址
    Support Web Application Projects
    CSS使用高级技巧20则
    apache和IIS共用80端口
    Dreamweaver扩展(插件)使用
    CSS横向菜单下拉显示子菜单
    openPNE创建项目
    基础AJAX
    连接数据库
  • 原文地址:https://www.cnblogs.com/jingLongJun/p/4518234.html
Copyright © 2020-2023  润新知