首页 > 代码库 > 搜索引擎系列 ---lucene简介 创建索引和搜索初步

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

 一、什么是Lucene?

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

Lucene 是一个 JAVA 搜索类库,它本身并不是一个完整的解决方案,需要额外的开发工作。

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

缺点:需要额外的开发工作。所有的扩展,分布式,可靠性等都需要自己实现;非实时,从建索引到可以搜索中间有一个时间延迟,而当前的“近实时”(Lucene Near Real Time search)搜索方案的可扩展性有待进一步完善。

对于全文检索一般都由以下3个部分组成:

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

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

目前基于Lucene的产品有:

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

 

二、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包进行开发。

 

三、索引创建

1、创建Directory

2、创建IndexWriter

3、创建Document对象

4、为Docuemnt添加Field

5、通过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 {            //1、创建Directory             directory = FSDirectory.open(new File(indexDir));            //RAMDirectory directory = new RAMDirectory();            //2、创建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();                //3、创建Docuemnt对象                Document document = new Document();                //4、为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));                //5、通过IndexWriter添加文档索引中                indexWriter.addDocument(document);            }        } catch (IOException e) {            e.printStackTrace();        } finally {            if (indexWriter != null) {                try {                    indexWriter.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}

 

 

注:

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

       2、Document相当于数据库中的一条记录,field相当数据库中表的一列;

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

       4、fieldType可以设置是否需要索引和是否需要存储;

       5、记得关闭indexWriter

 

 

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

 

 

四、搜索记录

 

1、创建Directory

2、创建IndexReader

3、根据IndexReader创建IndexSearcher

4、创建搜索的Query

5、根据Searcher搜索并且返回TopDocs

6、根据TopDocs获取ScoreDoc对象

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

8、根据Document对象获取需要的值

 

 public void search() {        IndexReader indexReader = null;        try {            //1、创建Directory            FSDirectory directory = FSDirectory.open(new File(indexDir));            //2、创建IndexReader             indexReader = DirectoryReader.open(directory);            //3、根据IndexReader创建IndexSearcher            IndexSearcher indexSearcher = new IndexSearcher(indexReader);            //4、创建搜索的Query            //创建querypaser来确定要搜索文件的内容,第二个参数表示搜索的域            QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());            //创建query,表示搜索域为content中包含java的文档            Query query = queryParser.parse("java");            //5、根据Searcher搜索并且返回TopDocs            TopDocs topDocs = indexSearcher.search(query, 100);            //6、根据TopDocs获取ScoreDoc对象            ScoreDoc[] sds = topDocs.scoreDocs;            //7、根据Seacher和ScoreDoc对象获取具体的Document对象            for (ScoreDoc sdc : sds) {                Document doc = indexSearcher.doc(sdc.doc);                //8、根据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 {            //1、创建Directory            directory = FSDirectory.open(new File(indexDir));            //RAMDirectory directory = new RAMDirectory();            //2、创建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();                //3、创建Docuemnt对象                Document document = new Document();                //4、为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));                //5、通过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 {            //1、创建Directory            FSDirectory directory = FSDirectory.open(new File(indexDir));            //2、创建IndexReader             indexReader = DirectoryReader.open(directory);            //3、根据IndexReader创建IndexSearcher            IndexSearcher indexSearcher = new IndexSearcher(indexReader);            //4、创建搜索的Query            //创建querypaser来确定要搜索文件的内容,第二个参数表示搜索的域            QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());            //创建query,表示搜索域为content中包含java的文档            Query query = queryParser.parse("java");            //5、根据Searcher搜索并且返回TopDocs            TopDocs topDocs = indexSearcher.search(query, 100);            //6、根据TopDocs获取ScoreDoc对象            ScoreDoc[] sds = topDocs.scoreDocs;            //7、根据Seacher和ScoreDoc对象获取具体的Document对象            for (ScoreDoc sdc : sds) {                Document doc = indexSearcher.doc(sdc.doc);                //8、根据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

 

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