zoukankan      html  css  js  c++  java
  • 2、Lucene 最简单的使用(小例子)

    在了解了Lucene以后,我打算亲手来做一个Lucene的小例子,这个例子只是Lucene最简单的应用:使用Lucene实现标准的英文搜索;

    1、下载Lucene

    下载Lucene,到Lucene的官方下载http://lucene.apache.org/;

    2、新建项目

    新建一个Java Project 然后引入Lucene的jar 包:

    因为要实现的功能非常简单,所以Jar包只引入了一部分,当然Lucene的jar包远远不止这些;

    core包:Lucene的核心包

    analyzers包:主要进行对采集的内容和用户输入的内容进行分词;

    highlighter包:主要对搜索的结果进行高亮显示,就像百度搜索结果标红一样;

    queries和queryparser包:搜索查询包,根据用户输入关键定去检索内容;

    主要用到这三个包; 

    3、准备数据源文件

    要让用户搜索结果,首先得有数据源, 我准备了几个文本文档,里面全是英文内容:

    将这些文本文件放在一个全英文的目录里面,同时还要建一些纯英文的目录用来存放索引文件;

    4、对数据源进行索引

    在用户进行搜索前,系统得先对数据源进行分析,排序,分词,创建索引;这是一步很关键的工作:

    新建一个CreateIndex类,代码如下:

    package com.lucene;
    import java.io.File;
    import java.util.Collection;
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.io.filefilter.TrueFileFilter;
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.analysis.util.CharArraySet;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field.Store;
    import org.apache.lucene.document.StringField;
    import org.apache.lucene.document.TextField;
    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;
    import org.junit.Test;
    
    public class CreateIndex {
            /** 数据源目录 **/
            public static final String DATA_DIR="E:/data/lucene/en/data";
            /** 索引目录 **/
            public static final String INDEX_DIR="E:/data/lucene/en/index";
            @Test
            public void create(){
                try {
                    Directory dir = FSDirectory.open(new File(INDEX_DIR));
                    //4. 通过CharArraySet可以向分词中追加一些停止词(即排除检索的词)
                    CharArraySet arrSet = new CharArraySet(Version.LUCENE_4_9, 0, false);
                    //3. Analyzer 用于对数据源进行分词
                    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9, arrSet);
                    //2. IndexWriter的配置信息都存放在IndexWriterConfig中
                    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9,analyzer);
                    // OpenMode.CREATE_OR_APPEND 指定,该创建索引是可以在以后通过追加的方式向里面添加内容
                    config.setOpenMode(OpenMode.CREATE_OR_APPEND);
                    //1. 创建索引的入口,创建索引必须用IndexWriter进行创建或者追加
                    IndexWriter writer = new IndexWriter(dir,config);
                    File dataDir = new File(DATA_DIR);
                    //5.得到数据源中所有的文件
                    Collection<File> files = FileUtils.listFiles(dataDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
                    for(File file : files){
                        //6. 通过向Writer追加Document的方式添加内容
                        Document doc = new Document();
                        doc.add(new StringField("filename",file.getName(), Store.YES));
                        String content = FileUtils.readFileToString(file);
                        doc.add(new TextField("content",content,Store.YES));
                        writer.addDocument(doc);
                    }
                    writer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    }

    在新建完CreateIndex类以后,可以使用Test运行一下,然后在索引目录就会生成一些这样的文件:

    这就是Lucene创建完索引的索引数据库了;

    5、创建检索

    创建一个SearchIndex类,主要作用是通过用户输入内容分词,然后检索出用户想要的结果:

    import java.io.File;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.index.DirectoryReader;
    import org.apache.lucene.index.IndexReader;
    import org.apache.lucene.queryparser.classic.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.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.apache.lucene.util.Version;
    import org.junit.Test;
    
    public class SearchIndex {
        @Test
        public void search(){
            try {
                String keyword = "java";
                // 在这里进行检索的时候,需要加载的目录就是创建索引的目录,创建索引以后,那些原数据源在Lucene上就暂时用不到了
                Directory directory = FSDirectory.open(new File(CreateIndex.INDEX_DIR));
                IndexReader reader = DirectoryReader.open(directory);
                // IndexSearcher 是Lucene的检索的入口点,所有检索都从这里入口
                IndexSearcher searcher = new IndexSearcher(reader);
                // 通过analyzer对用户输入的词进行分词
                StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9);
                // 构建检索条件
                QueryParser parser = new QueryParser(Version.LUCENE_4_9, "content",analyzer);
                Query query = parser.parse(keyword);
                // 最后使用searcher.search检索,search方法的参数很多,还可以根据需求,取出相应的条数
                TopDocs topDocs = searcher.search(query, 20);
                // topDocs.totalHits 返回的是所有检索到记录的条数的总和
                ScoreDoc[] docs = topDocs.scoreDocs;
                System.out.println("关键词" "+keyword+" "共检索到 "+topDocs.totalHits+" 条相关的记录");
                System.out.println("被检索到记录,他们分别放在以下的文件中:");
                for(ScoreDoc doc : docs){
                    int docId = doc.doc;
                    Document document = reader.document(docId);
                    System.out.println(document.get("filename"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    为了方便,我摸拟了一个搜索词“java” 看能查询出多少条数据,运行单元测试:

    小结:这只是Lucene的最简单的用法,还有很多高深的用法,可以查看Lucene的官方文档,Lucene用来检索中文同样很厉害,大家快去试试吧;下小节我会贴出我写的使用Lucene来做一个千度搜索;

  • 相关阅读:
    mac 配置 iterm2
    python面试题
    待办事项--flask
    八皇后问题c语言版(xcode下通过)
    对分布式一些理解
    观察者模式
    用redis实现悲观锁(后端语言以php为例)
    只用200行Go代码写一个自己的区块链!(转)
    php的生命周期的概述
    linux网络编程1 最简单的socket编程
  • 原文地址:https://www.cnblogs.com/raphael5200/p/5146773.html
Copyright © 2011-2022 走看看