• 用Lucene4.5对中文文本建立索引


      这里需要完成一个能对txt文本建立索引,并能完成检索查询。完成这个功能,使用的是Lucene4.5,同时使用其自带的中文分析器。

      准备工作是在一个文件夹里面建一些txt文件,这是我的文件结构:

      

      首先要对这些文本建立索引,代码如下

     1 package com.test;
     2 
     3 import java.io.*;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
     7 import org.apache.lucene.document.*;
     8 
     9 import org.apache.lucene.index.IndexWriter;
    10 import org.apache.lucene.index.IndexWriterConfig;
    11 import org.apache.lucene.store.Directory;
    12 import org.apache.lucene.store.FSDirectory;
    13 import org.apache.lucene.util.Version;
    14 
    15 public class Indexer {
    16 
    17     /**
    18      * @param args
    19      */
    20     
    21     private static String fileInput = "C:\Users\Press-Lab\Desktop\五月天歌词文件"; 
    22     //此处是索引存放的路径
    23     private static String indexPath = "C:\Users\Press-Lab\Desktop\index"; 
    24     
    25     public static void main(String[] args) throws Exception {
    26         // TODO Auto-generated method stub
    27         //此处去处txt的内容和路径,装入list中,方便下一步放入document中
    28         File[] files = new File(fileInput).listFiles();
    29         List<FileBag> list = new ArrayList<FileBag>();
    30         for(File f : files){
    31             BufferedReader br = new BufferedReader(new FileReader(f));
    32             StringBuffer sb = new StringBuffer(); 
    33             String line = null;
    34             while((line = br.readLine()) != null){
    35                 sb.append(line);
    36             }
    37             br.close();
    38             FileBag fileBag = new FileBag();
    39             fileBag.setContent(sb.toString());
    40             fileBag.setPath(f.getAbsolutePath());
    41             list.add(fileBag);
    42         }
    43         
    44         //此处为建立索引
    45         Directory dir = FSDirectory.open(new File(indexPath));
    46         //此处使用自带的中文分析器
    47         SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_45);
    48         IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45, analyzer);
    49         IndexWriter writer = new IndexWriter(dir, config);
    50         
    51         //对list中的每一个对象,分别连击索引
    52         for(FileBag fileBag : list){
    53             Document doc = new Document();
    54             doc.add(new Field("contents", fileBag.getContent(), Field.Store.YES,Field.Index.ANALYZED));
    55             doc.add(new StringField("path", fileBag.getPath(), Field.Store.YES));
    56             writer.addDocument(doc);
    57         }
    58         
    59         writer.close();
    60         
    61     }
    62 
    63 }
    64 //建立一个与txt对应的domain对象
    65 class FileBag{
    66     private String content;
    67     private String path;
    68     public String getContent() {
    69         return content;
    70     }
    71     public void setContent(String content) {
    72         this.content = content;
    73     }
    74     public String getPath() {
    75         return path;
    76     }
    77     public void setPath(String path) {
    78         this.path = path;
    79     }
    80     
    81     
    82 }

      在这段代码中,我对文本进行了存储,一般情况下是无需存储的,这里为为了方便查看结果才进行存储。

      特别注意代码的54行,如果使用Lucene4.5推荐的TextField,这无法建立索引。不知道这是个什么原因,有人解决过这个问题的麻烦告知下。

      下面是进行检索的代码:

     1 package com.test;
     2 
     3 import java.io.*;
     4 
     5 import org.apache.lucene.analysis.Analyzer;
     6 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
     7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
     8 import org.apache.lucene.document.Document;
     9 import org.apache.lucene.index.DirectoryReader;
    10 import org.apache.lucene.index.IndexReader;
    11 import org.apache.lucene.index.Term;
    12 
    13 
    14 import org.apache.lucene.queryparser.classic.QueryParser;
    15 import org.apache.lucene.search.IndexSearcher;
    16 
    17 import org.apache.lucene.search.Query;
    18 import org.apache.lucene.search.ScoreDoc;
    19 import org.apache.lucene.search.TermQuery;
    20 import org.apache.lucene.search.TopDocs;
    21 import org.apache.lucene.store.Directory;
    22 import org.apache.lucene.store.FSDirectory;
    23 import org.apache.lucene.util.Version;
    24 
    25 import com.dong.Constants;
    26 
    27 public class Seacher {
    28 
    29     /**
    30      * @param args
    31      */
    32     private static String indexPath = "C:\Users\Press-Lab\Desktop\index"; 
    33     public static void main(String[] args) throws Exception {
    34         // TODO Auto-generated method stub
    35         
    36            Directory dir=FSDirectory.open(new File(indexPath)); 
    37            IndexReader reader=DirectoryReader.open(dir);  
    38            IndexSearcher searcher=new IndexSearcher(reader);  
    39            //此处也需要是用中文分析器
    40            SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_45);
    41            QueryParser parser = new QueryParser(Version.LUCENE_45, "contents", analyzer);
    42            Query query = parser.parse("如果") ; 
    43            
    44            TopDocs topdocs=searcher.search(query, 5);  
    45            ScoreDoc[] scoreDocs=topdocs.scoreDocs;  
    46            
    47            System.out.println("共有数据:" +  topdocs.scoreDocs.length + "条"); 
    48            for(int i=0; i < scoreDocs.length; i++) {  
    49                 int doc = scoreDocs[i].doc;  
    50                 Document document = searcher.doc(doc);  
    51                 System.out.println("第" + i + "条文本的路径是:  " + document.get("path"));  
    52                 System.out.println("第" + i + "条文本内容是:   " + document.get("contents"));  
    53                 
    54             }  
    55             reader.close();  
    56     }  
    57 
    58         
    59     
    60 
    61 }

      这里需要注意的是,查询时候也需要中文分析器。

      下一篇要做的是,实现索引的分页查询。

      

  • 相关阅读:
    TyporaRecord
    c# 串口 应答式顺序下发命令 循环 间隔发送指令
    WPF 如何在单独的配置文件中使用Log4net
    UWP VisualStateManager
    USB通信
    UWP RelativePanel
    JSON 序列化与反序列化
    Unity 依赖注入的三种常用模板
    IOC Unity容器的基本使用
    使用EF完成基于SQLite的CodeFirst
  • 原文地址:https://www.cnblogs.com/dongqiSilent/p/3489678.html
Copyright © 2020-2023  润新知