全文检索技术--Lunce

1   课程计划

1、什么是全文检索,如何实现全文检索

2、Lucence实现全文检索的流程

   1)创建索引

   2)查询索引

3、配置开发环境

4、入门程序

5、分析器的分析过程

   1)测试分析器的分词效果

   2)第三方中文分析器

6、索引库维护

   1)添加文档

   2)删除文档

   3)修改文档

7、索引库查询

   使用query子类查询

   使用queryparser查询

2  什么是全文检索

什么是全文检索,搜索

数据的分类:可以分为在二类,

     1)结构化数据

               格式固定,长度固定,数据类型固定

              例如数据库中的数据

  2)非结构化数据

        word文档,pdf文档、邮件、html

     格式不固定,长度不固定,数据类型不固定

2、数据的查询

  1)结构化数据的查询

         SQL语句,查询结构化数据的方法,简单、速度快。

   2)非结构化数据的查询。

           从文本文件中,中找到包含spring单词的文件。

           1、目测

          2、使用程序文档读取到内存中,然后匹配字符串,顺序扫描

          3、把结构化数据变成结构化数据。

先根据空格进行字符串拆分,得到一个单词列表,基于单词列表创建一个索引。

索引:一个为了提高查询速度,创建某种数据结构的集合。

3)全文检索

   先创建索引,然后查询索引的过程叫做全文检索。

索引一次创建多次使用,表现为每次查询速度很快。

4)全文检索的应用场景

1、搜索引擎

2、站内搜索

电商搜索

只要是有搜索的地方就可以使用全文检索技术

三、什么是Lucene

Luncene是一个基于java开发的全文检索工具包

四、Luncene实现全文检索的流程

创建索引,查询索引

1、创建索引,

     1)获得文档    原始文档:要基于那些数据来进行搜索,那么这些数据就是原始文档。

    搜索引擎:使用爬虫

原始文件--》创建文档对晚---》分析文档---》根据空格

原始文档:要基于那些数据进行搜索,那么这些数据就是原始文档

搜索引擎:使用爬虫获得原始文档

站内搜索,数据库中的数据

案例,直接使用io流读取磁盘上的文件

2)构建文档对象

对应每个原始文档创建一个document对象

每个Document对象中包含 多个域

域中保存就是原始文档数据

域的名称

域 的值

每个文档都有一个唯一的编号,就是文档id

3)分析文档

就是分词的过程

根据空格进行字符串的拆分,得到一个单词的列表

把单词统一转换成小写

去掉标点符号

去除停用词,无意义的词

每个关键词都封装成一个term对象中

term中包含 两部分内容:关键词

    关键词的所有的域 

   关键词本身

   不同域 中拆行相同是不同的term

  创建索引:基于关键字列表创建一个索引,保存到索引库中

索引库中关含,索引,docuemnt 对象,关键字和文档的对应关系

查询索引:

    用户查询接口

     用户输入查询条件的地方

   例如:百度查询搜索框

把关键字,封装成一个查询对象

    要查询的域 

    要搜索的关键字

执行查询:根据要查询的关锓词到对应的域上进行搜索

找到关键字,

4)渲染结果:

根据文档的id找到文档对象

对关键词进行高亮显示

分页处理

最终展示给用户看

入门程序:

需求:

实现一个文件的搜索功能,通过关键字,搜索文件,凡是文件名

1、创建索引

环境:下载luncen

http:luncen.apache.org

步骤:

1、创建一个索引库,指定索引保存的位置

2、基于directory对象创建一个indexwriter对象

3、读取磁盘上的文件,每个文件创建一个文档对象

4、

package com.wangjunji;

import jdk.internal.org.objectweb.asm.tree.analysis.Analyzer;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Dictionary;

public class LuncenFirst {
    public static void createIndex() throws IOException {
        //创建 director对象,指定索引库保存位置
        // new RAMDirectory()
        //保存到磁盘上
        FSDirectory directory = FSDirectory.open(new File("F:\\code\\Luncene\\index").toPath());
        //基于dirctory对象,创建一个indexwriter对象
        IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
        //读取磁盘文件,对应每个文件创建一个文档对象
        File dir = new File("F:\\code\\Luncene\\searchsource");
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".txt");
            }
        });
        for (File file : files) {
            String fileName = file.getName();
            String filePath = file.getPath();
            String fContext = FileUtils.readFileToString(file,"utf-8");
            long fileSize = FileUtils.sizeOf(file);
            //创建Filed
            Field filldName = new TextField("name",fileName,Field.Store.YES);
            Field filldPath = new TextField("path",filePath,Field.Store.YES);
            Field filldContext = new TextField("content",fContext,Field.Store.YES);
            Field filldSize = new TextField("size",fileSize+"",Field.Store.YES);
            //创建文档对象
            Document document = new Document();
            document.add(filldName);
            document.add(filldPath);
            document.add(filldContext);
            document.add(filldSize);
            //对文件对象写入索引库
            indexWriter.addDocument(document);

        }
        indexWriter.close();
    }

    //查询索引库
    //步骤:创建一个dirctor对象。指定索引库的位置
    //创建一个indexreader对象
    //创建一个indexsearcher对象,构造方法中的参数indexReader对易用
    //创建一个query对象,termquery
    //执行查询,得到一个topdoc对象
    //取查询得到一个topdocs对象
    //取查询结果的总记录数
    //取文档列表
    //打印文档的内容
    //关闭idnexread
    public static void searchIndex() throws IOException {
        FSDirectory directory = FSDirectory.open(new File("F:\\code\\Luncene\\index").toPath());
        //基于dirctory对象,创建一个indexwriter
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //创建一个query对象
        Query query = new TermQuery(new Term("content","spring"));
        TopDocs topDocs = indexSearcher.search(query, 10);
        System.out.println("查询总记录数"+topDocs.totalHits);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            int docId = scoreDoc.doc;
            Document doc = indexSearcher.doc(docId);
            System.out.println(doc.get("name"));
            System.out.println(doc.get("path"));
            System.out.println(doc.get("content"));
            System.out.println(doc.get("size"));
        }
        indexReader.close();
    }

    //查看分词器分词效果
    public static void testTokenStream() throws Exception{
        StandardAnalyzer analyzer = new StandardAnalyzer();
        TokenStream tokenStream = analyzer.tokenStream("", "王马丁靴有东西暮云春霏霏封面");
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
        tokenStream.reset();
        while (tokenStream.incrementToken()){
            System.out.println(charTermAttribute.toString());
        }
        tokenStream.close();

    }

    public static void main(String[] args) throws Exception {
        //createIndex();
        //searchIndex();
        testTokenStream();
    }
}

       

     2)非结构化数据

  

发布了158 篇原创文章 · 获赞 28 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/wangjunji34478/article/details/105254348