zoukankan      html  css  js  c++  java
  • lucene 3.6.0学习总结

     目前,主流的全文索引工具有:Lucene , Sphinx , Solr , ElasticSearch。其中Solr和Elastic Search都是基于Lucene的。Sphinx不是 apache的项目,如果你想把Sphinx放到某个商业性的项目中,你就得买个商业许可证。(其实我只学习了lucence,solr 只是了解,这两天项目需要,研究学习了下.此文为个人学习备忘之用)

    第一章 LUCENE基础

    在全文索引工具中,都是由这样的三部分组成:索引部分、分词部分和搜索部分

      IndexWriter:用来创建索引并添加文档到索引中。

           Directory:这个类代表了索引的存储的位置,是一个抽象类。

           Analyzer:对文档内容进行分词处理,把分词后的内容交给 IndexWriter来建立索引。

           Document:由多个Field组成,相当于数据库中的一条记录。

           Field相当于数据库中的一条记录中的一个字段。

     

    分词部分的核心类

     


     

           Analyzer:简单分词器(SimpleAnalyzer)、停用词分词器(StopAnalyzer)、空格分词器(WhitespaceAnalyzer)、标准分词器(StandardAnalyzer)。

     

           TokenStream:可以通过这个类有效的获取到分词单元信息。

     

           Tokenizer:主要负责接收字符流Reader,Reader进行分词操作。

     

           TokenFilter:将分词的语汇单元,进行各种各样过滤。

     

     

    搜索部分的核心类

           IndexSearcher:用来在建立好的索引上进行搜索。

           Term:是搜索的基本单位。

           Query:把用户输入的查询字符串封装成Lucene能够识别的Query

           TermQuery:是抽象类Query的一个子类,它的构造函数只接受一个参数,那就是一个Term对象

           TopDocs:保存返回的搜索结果。

           SocreDoc:保存具体的Document对象。

    第二章 索引建立

    索引的建立是将现实世界中所有的结构化和非结构化数据提取信息,创建索引的过程。如下图:

    示例子:

    package text;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Date;
    
    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;
    import org.apache.lucene.document.NumericField;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.index.IndexWriterConfig;
    import org.apache.lucene.index.IndexWriterConfig.OpenMode;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.apache.lucene.util.Version;
    public class TestFileIndexer {
    	public   static   void  main(String[] args)  throws  Exception  {             
            /*  指明要索引文件夹的位置,这里是C盘的source文件夹下  */          
            File fileDir  =   new  File( "c:\source " );    
            /*  这里放索引文件的位置  */         
            File indexDir  =   new  File( "c:\index" );            
            Directory dir=FSDirectory.open(indexDir);//将索引存放在磁盘上  
            Analyzer lucenAnalyzer=new StandardAnalyzer(Version.LUCENE_36);//分析器  
            IndexWriterConfig iwc=new IndexWriterConfig(Version.LUCENE_36,lucenAnalyzer);  
            iwc.setOpenMode(OpenMode.CREATE);//创建新的索引文件create 表示创建或追加到已有索引库  
            IndexWriter indexWriter=new IndexWriter(dir,iwc);//把文档写入到索引库  
            File[] textFiles=fileDir.listFiles();//得到索引文件夹下所有文件  
            long startTime=new Date().getTime();  
            //增加document到检索去  
            for (int i = 0; i < textFiles.length; i++) {  
    //          if (textFiles[i].isFile()&& textFiles[i].getName().endsWith(".txt")) {  
                    System.out.println(":;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");  
                    System.out.println("File"+textFiles[i].getCanonicalPath()+"正在被索引...");  
                    String temp=FileReaderAll(textFiles[i].getCanonicalPath(),"GBK");  
                    System.out.println(temp);  
                    Document document=new Document();  
                    Field FieldPath=new Field("path",textFiles[i].getPath(),Field.Store.YES,Field.Index.NO);  
                    Field FieldBody=new Field("body",temp,Field.Store.YES,Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS);  
                    NumericField modifiField=new NumericField("modified");//所以key为modified  
                    modifiField.setLongValue(fileDir.lastModified());  
                    document.add(FieldPath);  
                    document.add(FieldBody);  
                    document.add(modifiField);  
                    indexWriter.addDocument(document);  
                      
    //          }  
            }  
            indexWriter.close();  
            //计算一下索引的时间  
            long endTime=new Date().getTime();  
            System.out.println("花了"+(endTime-startTime)+"毫秒把文档添加到索引里面去"+fileDir.getPath());  
        }  
        public static String FileReaderAll(String FileName,String charset)throws IOException{  
            BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(FileName),charset));  
            String line=new String();  
            String temp=new String();  
            while ((line=reader.readLine())!=null) {  
                temp+=line;  
            }  
            reader.close();  
            return temp;  
        }     
    

         Field.Store.YES:存储。该值可以被恢复(还原)。

                NO:不存储。该值不可以被恢复,但可以被索引。

                Field.Index.ANALYZED:分词。

                NOT_ANALYZED:不分词。

                NOT_ANALYZED_NO_NORMS:不分词也不加权(即不存储NORMS信息)。

    查询索引的基本信息

    package text;
    
    
    import java.io.File;  
    import java.io.IOException;  
      
      
      
    import org.apache.lucene.analysis.Analyzer;  
    import org.apache.lucene.analysis.standard.StandardAnalyzer;  
    import org.apache.lucene.document.Document;  
    import org.apache.lucene.index.IndexReader;  
    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.FSDirectory;  
    import org.apache.lucene.util.Version; 
    
    public class TestQuery {
    	public static void main(String[] args) throws ParseException, IOException {  
            String index="c:\index";//搜索的索引路径  
            IndexReader reader=IndexReader.open(FSDirectory.open(new File(index)));  
            IndexSearcher searcher=new IndexSearcher(reader);//检索工具  
            ScoreDoc[] hits=null;  
            String queryString="测试";  //搜索的索引名称  
            Query query=null;  
            Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_36);  
            try {  
                QueryParser qp=new QueryParser(Version.LUCENE_36,"body",analyzer);//用于解析用户输入的工具  
                query=qp.parse(queryString);  
            } catch (Exception e) {  
                // TODO: handle exception  
            }  
            if (searcher!=null) {  
                TopDocs results=searcher.search(query, 10);//只取排名前十的搜索结果  
                hits=results.scoreDocs;  
                Document document=null;  
               for (int i = 0; i < hits.length; i++) {  
                    document=searcher.doc(hits[i].doc);  
                    String body=document.get("body");  
                    String path=document.get("path");  
                    String modifiedtime=document.get("modifiField");  
                    System.out.println(body+"        ");   
                    System.out.println(path);   
                }  
                if (hits.length>0) {  
                    System.out.println("找到"+hits.length+"条结果");  
                      
                }  
                searcher.close();  
                reader.close();  
            }  
              
      
        }  
    }
    

    索引文件作用

         索引建立成功后,会自动在磁盘上生成一些不同后缀的文件(如下图),这些文件缺一不可,这里简单的介绍下不同后缀名的文件都有些什么作用:

           

         .fdt :  保存域的值(即Store.YES属性的文件)。

         .fdx :  与.fdt的作用相同。

         .fnm :保存了此段包含了多少个域,每个域的名称及索引方式。

         .frq :  保存倒排表。数据出现次数(哪篇文章哪个词出现了多少次)。

         .nrm : 保存评分和排序信息。

         .prx :  偏移量信息。倒排表中每个词在包含此词的文档中的位置。

         .tii :   保存了词典(Term Dictionary)。也即此段包含的所有的词按字   典顺序的排序。

         .tis :   同上。存储索引信息。

         备注:

              如上图,具有相同前缀文件的属同一个段,图中共两个段 "_0" "_1"

              一个索引可以包含多个段,段与段之间是独立的,添加新文档可以生成新的段,不同的段可以合并。

              这些索引文件可以使用使用lukeall-3.5.0.jar打开,具体使用方法在后面的章节进行详述

              Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_36); 

            QueryParser qp=new QueryParser(Version.LUCENE_36,"body",analyzer);//用于解析用户输入的工具  
                 Query     query=qp.parse(queryString); 

       

    根据Query获取TopDocs

         TopDocs tds = searcher.search(query, 10); //返回10条数据

    根据TopDocs获取ScoreDoc

      ScoreDoc[] hits=null; 

     hits=results.scoreDocs; 

     Document document=null;  
               for (int i = 0; i < hits.length; i++) {  
                    document=searcher.doc(hits[i].doc);  
                    String body=document.get("body");  
                    String path=document.get("path");  
                    String modifiedtime=document.get("modifiField");  
                    System.out.println(body+"        ");   
                    System.out.println(path);   
                }

     

     

  • 相关阅读:
    curl 空格和转义符
    supervisor
    pandas 小笔记
    bert 进行文本相似度计算
    认股权证的会计处理
    企业所得税汇算清缴
    调整事项与非调整事项的区别
    centos 挂载windows 2003 smb
    如何获得带转义的json内容
    安装了vs2019 编译node-sass node-gyp 找不到编译器的解决方法
  • 原文地址:https://www.cnblogs.com/chizizhixin/p/5545301.html
Copyright © 2011-2022 走看看