`
i2534
  • 浏览: 183505 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lucene 2.9的简单使用

    博客分类:
  • util
阅读更多

项目做的很杂,又用到了lucene对特定文件的内容进行搜索,检查特定词汇。

经过查资料,看demo,实验,终于写出来了。

ps:网上的资料大部分很老啊,类老是对不上号。

 

先建立索引

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.wltea.analyzer.lucene.IKAnalyzer;
import vrvclient.util.ConfigUtil;
import vrvclient.util.FileListUtil;

/**
 *
 * @author lan
 */
public class Indexer extends Constants {

    private static final Log log = LogFactory.getLog(Indexer.class);

    public void index(File[] files, FileFilter filter) {
        if (files == null) {
            return;
        }
//        System.out.println(filter.getClass());
        Set<File> set = new HashSet<File>();
        for (File f : files) {//过滤掉不合要求的文件,如后缀,文件名等
            FileListUtil.list(f, filter, set);
        }
        File indexDir = new File(ConfigUtil.getIndexPath());//这里是获得索引文件的保存路径的
        Analyzer analyzer = new IKAnalyzer();//使用国产的IK分词器,很好很强大
        try {
            FSDirectory dir = FSDirectory.open(indexDir);//保存到硬盘上
            IndexWriter iw = new IndexWriter(dir, analyzer, !IndexReader.indexExists(dir), IndexWriter.MaxFieldLength.LIMITED);
            for (File f : set) {
                if (f.isFile()) {
//                    System.out.println(f.getAbsolutePath());
                    Document doc = new Document();
                    Reader reader = new FileReader(f);
                    doc.add(new Field(PATH, f.getAbsolutePath(), Field.Store.YES, Field.Index.ANALYZED));//保存路径
                    doc.add(new Field(FILE, reader));//保存文件
                    iw.addDocument(doc);
                    reader.close();
                }
            }
            iw.optimize();
            iw.close();
        } catch (CorruptIndexException ex) {
            log.error(ex.getMessage(), ex);
        } catch (LockObtainFailedException ex) {
            log.error(ex.getMessage(), ex);
        } catch (IOException ex) {
            log.error(ex.getMessage(), ex);
        }
    }
}
 

这个是搜索结果

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
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.wltea.analyzer.lucene.IKAnalyzer;
import vrvclient.util.ConfigUtil;

/**
 *
 * @author lan
 */
public class Searcher extends Constants {

    private static final Log log = LogFactory.getLog(Indexer.class);

    /**
     *
     * @param contents
     * @param combineMode true = and,false = or
     * @param limit -1=all
     */
    public Set<String> search(String[] contents, boolean combineMode, int limit) {
        Set<String> paths = new HashSet<String>();
        try {
            File indexDir = new File(ConfigUtil.getIndexPath());
            FSDirectory fsd = FSDirectory.open(indexDir);
            IndexSearcher is = new IndexSearcher(fsd, true);
            Analyzer analyzer = new IKAnalyzer();
            if (fsd.getFile().exists()) {
                QueryParser qp = new QueryParser(FILE, analyzer);
                StringBuilder sb = new StringBuilder();
                String jioner = "";
                if (combineMode) {//如果是and,则所有条件要同时满足
                    jioner = "+";
                }
                boolean b = true;
                for (String s : contents) {
                    s = s.replaceAll("\\s+", " AND ");//防止条件中的空格被看成“或”,把其变成“与”
                    if (!b) {
                        sb.append(" ");
                    }
                    sb.append(jioner).append("(").append(s).append(")");
                    b = false;
                }
                Query q = qp.parse(sb.toString());
                log.info(q.toString());
                if (limit == -1) {
                    limit = is.maxDoc();
                }

                TopDocs hits = is.search(q, limit);
                ScoreDoc[] sds = hits.scoreDocs;
                for (int i = 0; i < sds.length; i++) {
                    ScoreDoc sd = sds[i];
                    Document doc = is.doc(sd.doc);
//                    System.out.println("Hit:(" + sd.score + ")" + doc.toString());
//本来想同时得到命中次数,也就是词频,但是网上找到的都是老版本的,这里不能用。
                    paths.add(doc.get(PATH));//返回匹配的路径
                }
            }
            is.close();
        } catch (ParseException ex) {
            log.error(ex.getMessage(), ex);
        } catch (IOException ex) {
            log.error(ex.getMessage(), ex);
        }
        return paths;
    }
}

 

附用到的工具类:

import java.io.File;
import java.io.FileFilter;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author lan
 */
public final class FileListUtil {

//返回一定数量的符合要求的文件
    public static void list(File f, FileFilter filter, Set<File> set, int limit) {
        if (limit > -1 && set.size() >= limit) {
            return;
        }
        if (f == null) {
            return;
        }
        if (f.isFile()) {
            set.add(f);
        } else if (f.isDirectory()) {
            File[] files = null;
            if (filter == null) {
                files = f.listFiles();
            } else {
                files = f.listFiles(filter);
            }
            if (files != null) {
                for (File file : files) {
                    list(file, filter, set, limit);
                }
            }
        }
    }

//返回所有的符合要求的文件,不要担心set放不上,至少我的D盘资料盘都放进去都没有内存溢出
    public static void list(File f, FileFilter filter, Set<File> set) {
        if (f == null) {
            return;
        }
        if (f.isFile()) {
            set.add(f);
        } else if (f.isDirectory()) {
            File[] files = null;
            if (filter == null) {
                files = f.listFiles();
            } else {
                files = f.listFiles(filter);
            }
            if (files != null) {
                for (File file : files) {
                    list(file, filter, set);
                }
            }
        }
    }

//其实是打包工具类用到的
    public static void list(File f, FileFilter filter, String parent, Map<String, File> map) {
        if (f == null) {
            return;
        }
        String name = f.getName();
        if (parent != null) {
            name = parent + "/" + name;
        }
        if (f.isFile()) {
            map.put(name, f);
        } else if (f.isDirectory()) {
            File[] files = null;
            if (filter == null) {
                files = f.listFiles();
            } else {
                files = f.listFiles(filter);
            }
            if (files != null) {
                for (File file : files) {
                    list(file, filter, name, map);
                }
            }
        }
    }
}

 

常量类,大部分人用接口,但是我不太喜欢用接口来保存常量,虽然更方便点,但是不合规范。

public class Constants {//可以替换成枚举,没必要了

    protected static final String PATH = "path";
    protected static final String FILE = "file";
}
 

 

分享到:
评论

相关推荐

    Lucene2.9英文API

    **Lucene 2.9 API 深度解析** Lucene 是一个开源的全文检索库,由Apache软件基金会开发并维护。它为开发者提供了一种高效、可扩展的搜索引擎架构,使得在各种应用中实现复杂的全文搜索功能成为可能。本文将深入探讨...

    lucene 2.9 api

    《深入理解Lucene 2.9 API:全方位剖析与应用》 Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护。它为开发者提供了一个简单可扩展的接口,用于在各种数据存储中实现全文索引和搜索功能。本文将深入...

    Lucene.NET2.9搜索引擎源代码(C#)

    **Lucene.NET 2.9 搜索引擎源代码解析** Lucene.NET 是一个基于 Apache Lucene 的全文搜索引擎库,它是用 C# 实现的。Apache Lucene 是一个高性能、可扩展的信息检索库,广泛用于构建复杂的搜索功能。Lucene.NET ...

    自己修改的基于lucene.net 2.9和highlighter插件的简单例子

    在"DesktopSearch1"这个项目中,可能包含了一个简单的桌面搜索应用,这个应用使用Lucene.NET 2.9进行索引和搜索,同时利用Highlighter插件来高亮显示搜索结果。开发者可能已经对原版的Lucene.NET和Highlighter插件...

    lucene-2.9.2.jar包+源码

    此外,它还提供了一个简单的API,使得开发者可以方便地集成到自己的应用中。 总之,Lucene-2.9.2是一个功能强大的全文检索库,它的中文分词能力和TF-IDF搜索引擎设计,使得开发者能够构建高效、准确的信息检索系统...

    lucene.net 2.9.2 实现索引生成,修改,查询,删除实例

    在这个实例中,我们将深入探讨如何使用Lucene.NET 2.9.2来实现索引的生成、修改、查询和删除。 **一、索引生成** 首先,我们需要创建一个索引,这是全文检索的基础。在Lucene.NET中,我们通常会定义一个文档类,...

    lucene2.4.1

    作为Java编写的一个开源项目,Lucene为开发者提供了强大的文本检索功能,使得开发全文搜索引擎变得简单易行。在本文中,我们将深入探讨Lucene 2.4.1版本中的核心概念、架构以及其实现的全文搜索技术。 一、Lucene...

    利用开源工具搭建小型搜索引擎

    - **5.1 建立索引的一个简单例子**: 提供一个简单的示例来演示如何使用Lucene创建索引。 - **5.2 理解索引中的核心类**: 解释Lucene中用于索引操作的主要类的作用。 - **5.2.1 IndexWriter**: 用于创建和更新索引。...

    IKAnalyzer中文分词器V3.2.8使用手册

    | 3.2.0G及后续版本 | 兼容Lucene2.9及3.0版本 | 仅对solr1.4提供接口实现 | 请注意参考对应的版本使用手册以确保正确使用。 ##### 2.3 安装部署 IKAnalyzer的安装包包含了《IKAnalyzer中文分词器V3.X使用手册》...

    JAVA WEB典型模块与项目实战大全

    9.4 初步使用lucene全文搜索组件  9.5 新闻搜索引擎具体实现  9.6 小结  第10章 在线网上支付(jsp+servlet+javabean)  10.1 在线网上支付原理  10.2 在线网上支付功能工具类  10.3 发出支付请求过程  ...

    Big Data Glossary-大数据术语

    **2.9 Riak** Riak是一个高度可用的分布式NoSQL数据库,支持数据复制和故障恢复。它采用键值存储方式,支持多种数据类型。 **2.10 ZooKeeper** ZooKeeper是一个分布式协调服务,用于管理和维护分布式系统的元数据...

Global site tag (gtag.js) - Google Analytics