时间: 2020-08-23|54次围观|0 条评论

1、lucene的总体架构

1.1、lucene的特点

  • 高效、可扩展的全文检索库;
  • 仅支持纯文本的索引(Indexing)和搜索(Search);
  • 搜索排名——最好的结果显示在最前面;
  • 许多强大的查询类型:短语查询、通配符查询、近似查询、范围查询等;
  • 对字段级别搜索(如标题,作者,内容);
  • 可以对任意字段排序;
  • 支持搜索多个索引并合并搜索结果;
  • 支持更新操作和查询操作同时进行;
  • 灵活的切面、高亮、join和group by功能;
  • 速度快,内存效率高,容错性好;
  • 可选排序模型,包括向量空间模型和BM25模型;
  • 可配置存储引擎;

1.2、lucene的架构及处理过程

搜索引擎lucene(1):总体架构插图
架构及处理过程.png

2、索引及搜索过程

2.1、索引及搜索组件:

搜索引擎lucene(1):总体架构插图1
索引及搜索组件.png
  • 被索引的文档用Document对象 表示。
  • IndexWriter 通过函数addDocument 将文档添加到索引中,实现创建索引的过程。
  • Lucene 的索引是应用反向索引。
  • 当用户有请求时,Query 代表用户的查询语句。
  • IndexSearcher 通过函数search 搜索Lucene Index 。
  • IndexSearcher 计算term weight 和score 并且将结果返回给用户。
  • 返回给用户的文档集合用TopDocsCollector 表示。

2.2、索引及搜索实现:

搜索引擎lucene(1):总体架构插图2
索引及搜索实现.png

索引过程:

  • 创建一个IndexWriter 用来写索引文件,它有几个参数,INDEX_DIR 就是索引文件所存放的位置,Analyzer 便是用来对文档进行词法分析和语言处理的。
  • 创建一个Document 代表我们要索引的文档。
  • 将不同的Field 加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的Field 来表示,在本例子中,一共有两类信息进行了索引,一个是文件路径,一个是文件内容。其中FileReader 的SRC_FILE 就表示要索引的源文件。
  • IndexWriter 调用函数addDocument 将索引写到索引文件夹中。

搜索过程:

  • IndexReader 将磁盘上的索引信息读入到内存,INDEX_DIR 就是索引文件存放的位置。
  • 创建IndexSearcher 准备进行搜索。
  • 创建Analyer 用来对查询语句进行词法分析和语言处理。
  • 创建QueryParser 用来对查询语句进行语法分析。
  • QueryParser 调用parser 进行语法分析,形成查询语法树,放到Query 中。
  • IndexSearcher 调用search 对查询语法树Query 进行搜索,得到结果TopScoreDocCollector 。

3、Lucene模块结构

搜索引擎lucene(1):总体架构插图3
模块结构.png
  • Lucene 的analysis 模块主要负责词法分析及语言处理而形成Term 。
  • Lucene 的index 模块主要负责索引的创建,里面有IndexWriter 。
  • Lucene 的store 模块主要负责索引的读写。
  • Lucene 的QueryParser 主要负责语法分析。
  • Lucene 的search 模块主要负责对索引的搜索。
  • Lucene 的similarity 模块主要负责对相关性打分的实现。

4、lucene构建简单搜索

4.1、索引创建

public class Indexer {    private IndexWriter indexWriter;    public Indexer(String indexPath) throws IOException {        //索引初始化        Directory directory = FSDirectory.open(Paths.get(indexPath));        //配置分词器为CJK中文分词器        IndexWriterConfig writerConfig = new IndexWriterConfig(new CJKAnalyzer());        indexWriter = new IndexWriter(directory, writerConfig);        //删除所有索引,以防重复索引        indexWriter.deleteAll();    }    public void close() throws IOException{        indexWriter.close();    }    //将dataPath下的所有文件及文件夹进行索引    public int index(String dataPath) throws IOException{        File file = new File(dataPath);        if(!file.isFile()){            File[] fileNames = file.listFiles();            indexFile(file);            if(fileNames != null){                for (File f: fileNames){                    index(f.getCanonicalPath());                }            }            return 1;        }else{            indexFile(file);            return 1;        }    }    //对文件名及路径进行索引    private void indexFile(File f) throws IOException{        System.out.println("index file:" + f.getCanonicalPath());        Document d = new Document();        //文件名        d.add(new TextField("name", f.getName(), Field.Store.YES));        //路径        d.add(new TextField("path", f.getCanonicalPath(), Field.Store.YES));        int suffixIndex = f.getName().indexOf('.');        indexWriter.addDocument(d);    }}

4.2、搜索处理

public class Searcher {    public static void search(String indexDir, String q) throws IOException, ParseException {        // 得到读取索引文件的路径        Directory dir = FSDirectory.open(Paths.get(indexDir));        // 通过Dir得到路径下所有文件        IndexReader reader = DirectoryReader.open(dir);        // 建立索引查询器        IndexSearcher searcher = new IndexSearcher(reader);        // 实例化分析器        Analyzer analyzer = new StandardAnalyzer();        /********建立查询解析器********/        // 第一个参数是要查询的字段; 第二个参数市分析器Analyzer        String[] fields = {"name", "path"};        Map<String, Float> fieldMap = new HashMap<>();        fieldMap.put("name",100.0f);        fieldMap.put("path",1.0f);        QueryParser parser = new MultiFieldQueryParser(fields,new CJKAnalyzer());        // 根据传进来的q查找        Query query = parser.parse(q);        // 计算索引开始时间        long start = System.currentTimeMillis();        /********开始查询********/        // 第一个参数是通过传过来的参数来查找得到的query; 第二个参数是要查询出的行数        TopDocs hits = searcher.search(query,10);        // 计算索引结束时间        long end = System.currentTimeMillis();        System.out.println("匹配 "+ q + ",查询到 " + hits.totalHits + " 个记录, 用时:" + (end - start));        // 遍历hits.scoreDocs,得到scoreDoc        // scoreDoc:得分文档,即得到的文档  scoreDocs:代表topDocs这个文档数组        for (ScoreDoc scoreDoc : hits.scoreDocs) {            Document doc = searcher.doc(scoreDoc.doc);            System.out.println("name:" + doc.get("name") + " ,path=" + doc.get("path"));        }        //关闭reader        reader.close();    }}

4.3、测试及输出

测试代码:

public class Main {    private static  String INDEX_PATH = "D:\\index";    public static void main(String[] args){        try {            Indexer indexer = new Indexer(INDEX_PATH);            indexer.index("D:\\book");            indexer.close();            Searcher.search(INDEX_PATH,"mongodb");        }catch (Exception e){            System.out.println(e.getCause());        }    }}

输出结果:

index file:D:\bookindex file:D:\book\Elasticsearchindex file:D:\book\Elasticsearch\Elasticsearch 权威指南.pdfindex file:D:\book\Elasticsearch\ElasticSearch+可扩展的开源弹性搜索解决方案.pdfindex file:D:\book\Elasticsearch\ElasticSearchManual.pdfindex file:D:\book\Elasticsearch\elasticsearch介绍与使用-new.pptxindex file:D:\book\Elasticsearch\elasticsearch技术解析与实战.pdfindex file:D:\book\Elasticsearch\Elasticsearch服务器开发(第2版).pdfindex file:D:\book\Elasticsearch\Elasticsearch集成Hadoop最佳实践.pdfindex file:D:\book\Elasticsearch\ppt文档index file:D:\book\Elasticsearch\ppt文档\Elasticsearch 调研.pptxindex file:D:\book\Elasticsearch\ppt文档\elasticsearch介绍与使用-new.pptxindex file:D:\book\Elasticsearch\ppt文档\es geo.pptxindex file:D:\book\Elasticsearch\ppt文档\ES 创建索引代码流程.pptxindex file:D:\book\Elasticsearch\ppt文档\ES-Client研究.pptxindex file:D:\book\Elasticsearch\ppt文档\ES5  alpha4的leader选举.pptxindex file:D:\book\Elasticsearch\ppt文档\ES数据迁移.pptxindex file:D:\book\Elasticsearch\ppt文档\ES服务化实践.pptxindex file:D:\book\Elasticsearch\ppt文档\ES相关系统介绍.pptxindex file:D:\book\Elasticsearch\ppt文档\ES简介.pptxindex file:D:\book\Elasticsearch\大数据搜索与日志挖掘及可视化方案 ELK Stack Elasticsearch Logstash Kibana 第2版.pdfindex file:D:\book\Elasticsearch\深入理解ElasticSearch.pdfindex file:D:\book\java多线程index file:D:\book\java多线程\Java 并发编程实战.pdfindex file:D:\book\java多线程\Java多线程编程实战指南 设计模式篇.pdfindex file:D:\book\java多线程\Java多线程编程核心技术_完整版 PDF电子书下载 带书签目录.pdfindex file:D:\book\java多线程\java多线程设计模式详解.pdfindex file:D:\book\java多线程\java多线程设计模式详解PDF及源码.zipindex file:D:\book\java多线程\Java并发程序设计教程-2010-08-10.pdfindex file:D:\book\java多线程\Java并发编程的艺术.pdfindex file:D:\book\java多线程\Java并发编程:设计原则与模式(第二版).pdfindex file:D:\book\java多线程\lihaibo@netease.pptindex file:D:\book\java多线程\七周七并发模型.pdfindex file:D:\book\java多线程\分布式java应用-基础与实际.pdfindex file:D:\book\java虚拟机index file:D:\book\java虚拟机\HotSpot实战.pdfindex file:D:\book\java虚拟机\Java性能权威指南.pdfindex file:D:\book\java虚拟机\Java程序员修炼之道.pdfindex file:D:\book\java虚拟机\Java程序性能优化-.让你的Java程序更快、更稳定.pdfindex file:D:\book\java虚拟机\Java虚拟机规范  Java SE 8版@www.jqhtml.com.pdfindex file:D:\book\java虚拟机\深入理解Java虚拟机:JVM高级特性与最佳实践.pdfindex file:D:\book\java语言index file:D:\book\java语言\Java 8函数式编程.pdfindex file:D:\book\java语言\Java 8实战.pdfindex file:D:\book\Luceneindex file:D:\book\Lucene\Lucene 实战(第2版).pdfindex file:D:\book\Lucene\Lucene搜索引擎开发权威经典.pdfindex file:D:\book\Lucene\Lucene搜索引擎开发进阶实战www.java1234.com.pdfindex file:D:\book\Lucene\《从Lucene到Elasticsearch 全文检索实战》.pdfindex file:D:\book\Lucene\从Lucene到Elasticsearch:全文检索实战@www.java1234.com.pdfindex file:D:\book\Lucene\开放源代码的全文检索引擎Lucene.pdfindex file:D:\book\Lucene\解密搜索引擎技术实战  LUCENE &amp; JAVA精华版  第3版@www.java1234.com.pdfindex file:D:\book\mongodbindex file:D:\book\mongodb\MongoDB大数据处理权威指南  第2版 .pdfindex file:D:\book\mongodb\mongodb实战.pdfindex file:D:\book\mongodb\MongoDB权威指南第2版.pdfindex file:D:\book\《从Lucene到Elasticsearch 全文检索实战》.pdf匹配 mongodb,查询到 4 hits 个记录, 用时:184name:mongodb ,path=D:\book\mongodbname:mongodb实战.pdf ,path=D:\book\mongodb\mongodb实战.pdfname:MongoDB权威指南第2版.pdf ,path=D:\book\mongodb\MongoDB权威指南第2版.pdfname:MongoDB大数据处理权威指南  第2版 .pdf ,path=D:\book\mongodb\MongoDB大数据处理权威指南  第2版 .pdfDisconnected from the target VM, address: '127.0.0.1:50869', transport: 'socket'

github:https://github.com/zhaozhou11/search-demo.git

参考博客:

https://blog.csdn.net/forfuture1978/article/details/4745802

文章转载于:https://www.jianshu.com/p/8db867fa8a2a

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《搜索引擎lucene(1):总体架构
   

还没有人抢沙发呢~