搜索引擎系列 ---lucene简介 建立索引和搜索初步

 1、什么是Lucene?

Lucene最初是由Doug Cutting开发的,2000年3月,发布第一个版本,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎 ;Lucene得名于Doug妻子的中名,同时这也她外祖母的姓;目前是Apache基金会的一个顶级项目,同时也是学习搜索引擎入门必知必会。java

Lucene 是一个 JAVA 搜索类库,它自己并非一个完整的解决方案,须要额外的开发工做。数据库

优势:成熟的解决方案,有不少的成功案例。apache 顶级项目,正在持续快速的进步。庞大而活跃的开发社区,大量的开发人员。它只是一个类库,有足够的定制和优化空间:通过简单定制,就能够知足绝大部分常见的需求;通过优化,能够支持 10亿+ 量级的搜索。apache

缺点:须要额外的开发工做。全部的扩展,分布式,可靠性等都须要本身实现;非实时,从建索引到能够搜索中间有一个时间延迟,而当前的“近实时”(Lucene Near Real Time search)搜索方案的可扩展性有待进一步完善。架构

对于全文检索通常都由如下3个部分组成:分布式

  • 索引部分
  • 分词部分
  • 搜索部分

在接下来的一系列文章中会详细介绍这三个部分,本文将简单介绍lucene环境搭建以及lucene索引初步。ide

目前基于Lucene的产品有:oop

Solr,Nutch,Hbase,Katta,constellio,Summa,Compass,Bobo Search,Index Tank,Elastic Search,Hadoop contrib/index ,LinkedIn ,Eclipse,Cocoon学习

 

2、Lucene环境搭建

目录最新版的Lucene为4.10.0(今天是2014-09-22 )版,其官方主页为:http://lucene.apache.org/ 测试

或者点击下载优化

若是你会使用Maven,那么能够很是简单的将pom.xml中加入如下内容便可:

 

    <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>4.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>4.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>4.10.0</version>
        </dependency>

 

若是不会使用Maven,则须要手工下载相应的jar包进行开发。

 

3、索引建立

一、建立Directory

二、建立IndexWriter

三、建立Document对象

四、为Docuemnt添加Field

五、经过IndexWriter添加文档到Document

 

package com.amos.lucene;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.IndexableFieldType;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by amosli on 14-9-17.
 */
public class HelloLucene {
   static String indexDir = "/home/amosli/developtest/lucene";

    public void index() {
        IndexWriter indexWriter = null;
        FSDirectory directory = null;
        try {
            //一、建立Directory
             directory = FSDirectory.open(new File(indexDir));
            //RAMDirectory directory = new RAMDirectory();

            //二、建立IndexWriter
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_0, new StandardAnalyzer(Version.LUCENE_4_10_0));
            indexWriter = new IndexWriter(directory, indexWriterConfig);

            File file = new File("/home/amosli/developtest/testfile");
            for (File f : file.listFiles()) {

                FieldType fieldType = new FieldType();
                //三、建立Docuemnt对象
                Document document = new Document();

                //四、为Document添加Field
                document.add(new TextField("content", new FileReader(f)) );

                fieldType.setIndexed(true);
                fieldType.setStored(true);
                document.add(new Field("name", f.getName(),fieldType));

                fieldType.setIndexed(false);
                fieldType.setStored(true);
                document.add(new Field("path", f.getAbsolutePath(), fieldType));

                //五、经过IndexWriter添加文档索引中
                indexWriter.addDocument(document);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (indexWriter != null) {
                try {
                    indexWriter.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

 

 

注:

  一、这里使用的是FSDirectory,是为了方便进行测试,将生成的文件写入到本地硬盘中;

       二、Document至关于数据库中的一条记录,field至关数据库中表的一列;

       三、使用indexWriter当记录添加到文档索引中;

       四、fieldType能够设置是否须要索引和是否须要存储;

       五、记得关闭indexWriter

 

 

生成的索引文件,以下图所示:

 

 

4、搜索记录

 

一、建立Directory

二、建立IndexReader

三、根据IndexReader建立IndexSearcher

四、建立搜索的Query

五、根据Searcher搜索而且返回TopDocs

六、根据TopDocs获取ScoreDoc对象

七、根据Seacher和ScoreDoc对象获取具体的Document对象

八、根据Document对象获取须要的值

 

 public void search() {
        IndexReader indexReader = null;
        try {
            //一、建立Directory
            FSDirectory directory = FSDirectory.open(new File(indexDir));

            //二、建立IndexReader
             indexReader = DirectoryReader.open(directory);

            //三、根据IndexReader建立IndexSearcher
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);

            //四、建立搜索的Query
            //建立querypaser来肯定要搜索文件的内容,第二个参数表示搜索的域
            QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());
            //建立query,表示搜索域为content中包含java的文档
            Query query = queryParser.parse("java");
            //五、根据Searcher搜索而且返回TopDocs
            TopDocs topDocs = indexSearcher.search(query, 100);
            //六、根据TopDocs获取ScoreDoc对象
            ScoreDoc[] sds = topDocs.scoreDocs;
            //七、根据Seacher和ScoreDoc对象获取具体的Document对象
            for (ScoreDoc sdc : sds) {
                Document doc = indexSearcher.doc(sdc.doc);
                //八、根据Document对象获取须要的值
                System.out.println("name:" + doc.get("name") + "----->  path:" + doc.get("path"));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }finally{

            if(indexReader!=null){
                try {
                    indexReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

输出结果:

 

全部源码:HelloLucene.java 

package com.amos.lucene;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
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.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by amosli on 14-9-17.
 */
public class HelloLucene {
    static String indexDir = "/home/amosli/developtest/lucene";

    public void index() {
        IndexWriter indexWriter = null;
        FSDirectory directory = null;
        try {
            //一、建立Directory
            directory = FSDirectory.open(new File(indexDir));
            //RAMDirectory directory = new RAMDirectory();

            //二、建立IndexWriter
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_0, new StandardAnalyzer(Version.LUCENE_4_10_0));
            indexWriter = new IndexWriter(directory, indexWriterConfig);

            File file = new File("/home/amosli/developtest/testfile");
            for (File f : file.listFiles()) {

                FieldType fieldType = new FieldType();
                //三、建立Docuemnt对象
                Document document = new Document();

                //四、为Document添加Field
                document.add(new TextField("content", new FileReader(f)));

                fieldType.setIndexed(true);
                fieldType.setStored(true);
                document.add(new Field("name", f.getName(), fieldType));

                fieldType.setIndexed(false);
                fieldType.setStored(true);
                document.add(new Field("path", f.getAbsolutePath(), fieldType));

                //五、经过IndexWriter添加文档索引中
                indexWriter.addDocument(document);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (indexWriter != null) {
                try {
                    indexWriter.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void search() {
        IndexReader indexReader = null;
        try {
            //一、建立Directory
            FSDirectory directory = FSDirectory.open(new File(indexDir));

            //二、建立IndexReader
             indexReader = DirectoryReader.open(directory);

            //三、根据IndexReader建立IndexSearcher
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);

            //四、建立搜索的Query
            //建立querypaser来肯定要搜索文件的内容,第二个参数表示搜索的域
            QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());
            //建立query,表示搜索域为content中包含java的文档
            Query query = queryParser.parse("java");
            //五、根据Searcher搜索而且返回TopDocs
            TopDocs topDocs = indexSearcher.search(query, 100);
            //六、根据TopDocs获取ScoreDoc对象
            ScoreDoc[] sds = topDocs.scoreDocs;
            //七、根据Seacher和ScoreDoc对象获取具体的Document对象
            for (ScoreDoc sdc : sds) {
                Document doc = indexSearcher.doc(sdc.doc);
                //八、根据Document对象获取须要的值
                System.out.println("name:" + doc.get("name") + "----->  path:" + doc.get("path"));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }finally{

            if(indexReader!=null){
                try {
                    indexReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
View Code

TestHelloLucene.java

package com.amos.lucene;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.junit.Test;

/**
 * Created by amosli on 14-9-17.
 */
public class TestHelloLucene {
    @Test
    public void testIndex(){
        HelloLucene helloLucene = new HelloLucene();
        helloLucene.index();
    }
    @Test
    public void testSearch(){
        HelloLucene helloLucene = new HelloLucene();
        helloLucene.search();
    }
}
View Code
相关文章
相关标签/搜索