`

lucene之第一次亲密接触

 
阅读更多

 

1.最近想学lucene ,就去下了最新的3.5版本。发现这东西不错,值得玩玩。

 

整个步骤无非两步

1.建立索引

 先说怎么建立索引,几个核心的类

IndexWriterConfig:建立索引的配置对象,里面包含一个索引解析器Analyzer

IndexWriter:写索引的类。

好了要建立索引最为核心的就是上面两个类。

具体可以看代码

 

     package com.mingming.xue.lecene;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.io.IOUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.FieldInfo.IndexOptions;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class FileIndexer {

    private IndexWriter indexWriter;
   
   // 索引文件存放目录
    private File        fileIndex = new File(FileSearchConstant.FILE_INDEX);
   // 要被建立索引的文件目录
    private File        fileDir   = new File(FileSearchConstant.FILE_DIR);

    // private static Logger logger = LoggerFactory.getLogger(FileIndexer.class);

    public static void main(String[] args) throws IOException {
        FileIndexer fileIndexer = new FileIndexer();
        fileIndexer.buildIndex();

    }

    public void buildIndex() throws IOException {

        boolean isCreate = true;

        //建立索引的配置类,包含了一个解析器    
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35,
                                                                    new StandardAnalyzer(Version.LUCENE_35));
        //设置我们的解析器是新建还是追加更新
        setModel(isCreate, indexWriterConfig);
        
        //索引的建立类 第一个参数索引的存放位置,第二个参数索引的配置对象
        indexWriter = new IndexWriter(FSDirectory.open(fileIndex), indexWriterConfig);

        long startTime = System.currentTimeMillis();
        
        //建立索引
        indexDocs(fileDir, indexWriter);
        
        //这个方法在新增索引的情况会很有用,就是讲原来散落的索引文件重新进行整理合并! 
        indexWriter.forceMerge(1);
        // indexWriter.commit();

        // 关闭索引写
        indexWriter.close();

        long endTime = System.currentTimeMillis();

        System.out.println("cost :" + (endTime - startTime) + "seconds");

    }

    private void setModel(boolean isCreate, IndexWriterConfig indexWriterConfig) {
        if (isCreate) {
            indexWriterConfig.setOpenMode(OpenMode.CREATE);
        } else {
            indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
        }
    }

    private void indexDocs(File fileDir, IndexWriter indexWriter) throws CorruptIndexException, IOException {

        if (fileDir.canRead()) {

            if (fileDir.isDirectory()) {

                String[] listFiles = fileDir.list();
                for (String file : listFiles) {
                    indexDocs(new File(fileDir, file), indexWriter);
                }

            } else {
                
                // Document 代表一个索引类型件
                Document doc = new Document();

                // Field 代表索引的项,比如我们这里对文件的路径进行建索引
                Field pathField = new Field(FileSearchConstant.PATH, fileDir.getPath(), Field.Store.YES,
                                            Field.Index.NOT_ANALYZED_NO_NORMS);
                /*索引建立有两个很关键的因素:
                  * Document Frequency 即文档频次
                  * Document Frequency (df):即有多少文档包含次Term。df 越大说明越不重要
                  * 这里代表在建索引时不考虑这两点,只建立索引
                 */
                pathField.setIndexOptions(IndexOptions.DOCS_ONLY);
                doc.add(pathField);

                // NumericField modifyField = new NumericField(IndexerConstant.MODIFIED);
                // modifyField.setLongValue(fileDir.lastModified());
                // doc.add(modifyField);
                
                //对文件内容建立索引
                Field contentField = new Field(FileSearchConstant.CONTENTS, getContents(fileDir), Field.Store.YES,
                                               Field.Index.ANALYZED);

                // FileInputStream fileInputStream = getFileInputStream(fileDir);
                // doc.add(new Field(IndexerConstant.CONTENTS, new BufferedReader(new InputStreamReader(fileInputStream,
                // "UTF-8"))));
                // fileInputStream.close();
                contentField.setIndexOptions(IndexOptions.DOCS_ONLY);
                
                doc.add(contentField);
                
                //添加或是更新索引
                if (indexWriter.getConfig().getOpenMode() == OpenMode.CREATE) {
                    indexWriter.addDocument(doc);
                } else if (indexWriter.getConfig().getOpenMode() == OpenMode.CREATE_OR_APPEND) {
                    indexWriter.updateDocument(new Term(FileSearchConstant.PATH, fileDir.getPath()), doc);
                }

            }
        }

    }

    public String getContentByUtils(File fileDir) {

        String content = null;

        try {

            content = IOUtils.toString(new FileInputStream(fileDir), "UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }
    

    /*
    *  这个方法不推荐使用,在readline的时候没有把换行符带入,带入在建立索引的时候不能做正确的分词,建议使用上面那个文件读取
    */
    public String getContents(File fileDir) {

        StringBuffer result = new StringBuffer();
        BufferedReader reader = null;
        try {

            reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileDir), "UTF-8"));

            String temp = null;
            while ((temp = reader.readLine()) != null) {
                result.append(temp);
            }

        } catch (Exception e) {

            e.printStackTrace();
            return null;

        } finally {

            if (null != reader) {

                try {
                    reader.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result.toString();
    }

}
 

 

 

 

2.按照索引查找

直接看代码吧,不废话了。

 

package com.mingming.xue.lecene;

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 FileSearcher {

    private String content = "haha";

    public void search() throws IOException, ParseException {
         
        // FSDirectory.open(new File(FileSearchConstant.FILE_INDEX) 这个会根据你的操作系统类型,打开最为合适的索引读取器:简单文件读取,内存,NIO等三种
        IndexReader indexReader = IndexReader.open(FSDirectory.open(new File(FileSearchConstant.FILE_INDEX)));
        IndexSearcher searcher = new IndexSearcher(indexReader);
        
        //构建要查找的内容项
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
        QueryParser queryParser = new QueryParser(Version.LUCENE_35, FileSearchConstant.CONTENTS, analyzer);
        
        //解析内容
        Query query = queryParser.parse(content);
  
        System.out.println("Searching for: " + query.toString());
         
        //TopDocs是返回结果,10代表最大取10个,在实际应用中我们一般要做分页处理,所以这里需要特别注意下! 
        TopDocs topDocs = searcher.search(query, 10);
        ScoreDoc[] docs = topDocs.scoreDocs;

        if (null != docs) {

            for (int i = 0; i < docs.length; i++) {
                ScoreDoc scoreDoc = docs[i];
                //这步很重要的,也是最为关键的一步
                Document doc = searcher.doc(scoreDoc.doc);
               //取的自己想要的数据 
                String contents = doc.get(FileSearchConstant.CONTENTS);
                String path = doc.get(FileSearchConstant.PATH);
                System.out.println(contents);
                System.out.println(path);

            }
        }
    }

    public static void main(String[] args) throws IOException, ParseException {
        FileSearcher fileSearcher = new FileSearcher();
        fileSearcher.search();
    }
}
全部代码见附件,因为自己采用的是maven 构建,所以若要下载,请现装maven。
mvn install 
mvn eclipse:eclipse -DdownloadSources=true
这样既可查看代码及源码!
  • ll.zip (18.1 KB)
  • 下载次数: 19
分享到:
评论

相关推荐

    第一个lucene程序

    《第一个Lucene程序详解》 在信息技术领域,搜索引擎的实现是一项关键的技术,而Apache Lucene作为一款开源全文检索库,为开发者提供了强大的文本搜索功能。本文将深入探讨如何编写你的“第一个Lucene程序”,帮助...

    lucene的第一个程序

    创建一个indexwriter // 1)指定索引库的存放位置Directory对象 // 2)指定一个分析器,对文档内容进行分析 Directory directory = FSDirectory.open(new File&#40;"D:\\temp\\index"&#41;); Analyzer analyzer = ...

    lucene实战第二版(最新)

    本书由Lucene的核心开发者之一Erik Hatcher和另一位经验丰富的开发者Otis Gospodnetic合作撰写。这两位作者将他们在Lucene项目上的深厚经验转化为易于理解的教程,让任何不熟悉Lucene或搜索引擎开发的开发者都能在短...

    lucene in action 第二版

    《Lucene in Action 第二版》是一本专门介绍如何使用Lucene搜索引擎框架的书籍。Lucene是一个高性能的全文检索库,它允许开发者在应用程序中实现搜索功能。第二版意味着这本书经过了更新,以适应Lucene版本的变化。...

    Lucene之删除索引

    在深入探讨Lucene删除索引这一主题之前,我们先来理解一下Lucene的基本概念。Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发。它提供了高性能、可扩展的搜索和索引功能,广泛应用于各种应用程序中,如...

    lucene,lucene教程,lucene讲解

    第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。 第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。 public void add(Query query, BooleanClause.Occur occur) BooleanClause...

    Lucene实战中文版第2版

    经典的Lucene资源

    Lucene实战 第二版 完整清晰中文版

    Lucene实战第二版完整清晰中文版是一本介绍Lucene开源全文搜索引擎开发包的书籍。Lucene是一个用Java编写的功能强大的全文搜索引擎库,它以出色的可扩展性和快速的搜索特性获得了广泛的赞誉。本书详细介绍了如何有效...

    深入了解Lucene之一 系统结构分析.pptx

    Lucene是一款开源的全文搜索引擎库,广泛应用于各种信息检索系统中。本文将从系统结构、源码组织、数据流及其相互关系等多个角度,帮助读者深入理解Lucene的核心机制。 ### **1. 全文检索系统结构** 一个完整的...

    lucene3.0 lucene3.0

    lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0

    深入了解Lucene之四 主要算法介绍.ppt

    通过这种方式,Lucene可以有效地管理多个小索引段,避免一次性合并大量数据导致的性能瓶颈。 然后,归并算法是Lucene处理索引段合并的关键。由于各段内的Term已经排序,Lucene使用小根堆的数据结构来组织这些段。堆...

    Lucene in Action 中文版

    使用其他编程语言访问Lucene Lucene管理和性能调优等内容 最后还提供了三大经典成功案例 为读者展示了一个奇妙的搜索世界  《Lucene实战 第2版 》适合于已具有一定Java编程基本的读者 以及希望能够把强大的搜索...

    Lucene In Action 第二版 高清中文版+附书源代码

    《Lucene In Action 第二版》是一本深入探讨Apache Lucene全文搜索引擎库的专业书籍,高清中文版的提供为中文读者提供了便利。这本书由Michael McCandless等作者编写,旨在帮助开发者充分利用Lucene的强大功能,构建...

    Lucene的原理完整版pdf

    Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单但功能强大的API,用于索引和搜索文本数据,使得开发者可以轻松地在应用程序中实现复杂的...

    Lucene实战(第二版)

    《Lucene实战(第二版)》是一本深入探讨Apache Lucene全文搜索引擎库的权威书籍,主要面向对Java和搜索引擎技术感兴趣的开发者。这本书详尽地介绍了如何利用Lucene进行信息检索、文本分析和索引构建,同时也涵盖了...

    Lucene初探,一个初级的LuceneDemo

    **Lucene初探:一个初级的LuceneDemo** 在IT领域,搜索引擎技术是不可或缺的一部分,尤其是在大数据时代,高效的信息检索显得尤为重要。Apache Lucene就是这样一款强大的开源全文搜索引擎库,它为开发者提供了构建...

    Lucene实战第二版中英文PDF(带书签)

    《Lucene实战第二版》是关于全文搜索引擎Lucene的一本权威指南,由Michael McCandless、Erik Hatcher和Dave Bollinger共同撰写。这本书详细介绍了如何使用Java库Lucene来构建高性能、可扩展的搜索功能。以下是该书的...

    lucene第一天完整代码

    @Test public void testBooleanQuery() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); BooleanQuery booleanQuery = ... Query query2 = new TermQuery(new Term("fileName","lucene"));

Global site tag (gtag.js) - Google Analytics