lucene全文检索

3 篇文章 0 订阅
2 篇文章 0 订阅

lucene总结

一. lucene原理

1.索引和搜索流程图在这里插入图片描述
(1)绿色表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容采集文档创建文档分析文档索引文档

(2)红色表示搜索过程,从索引库中搜索内容,搜索过程包括:
用户通过搜索界面创建查询执行搜索,从索引库搜索渲染搜索结果

2. 创建索引

(1)对文档索引的过程,将用户要搜索的文档内容进行索引,索引存储在索引库(index)中。

(2)这里我们要搜索的文档是磁盘上的文本文件,根据案例描述:凡是文件名或文件内容包括关键字的文件都要找出来,这里要对文件名和文件内容创建索引。

3. 分析文档

将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。

4. 创建索引

(1)对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)。

注意:创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。
传统方法是根据文件找到该文件的内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大、搜索慢。
倒排索引结构是根据内容(词语)找文档,如下图: 在这里插入图片描述
倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它的规模
二. lucene使用

  1. 导入jar
  2. 创建索引

 //索引库还可以存放到内存中
 //Directory directory = new RAMDirectory();
 //指定索引库(存到硬盘上)存放的路径,参数是path路径
 Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
 
 //创建indexwriterCofig对象,用于指定以什么方法创建索引(默认Standard)
 IndexWriterConfig config = new IndexWriterConfig();
 
 //创建indexwriter对象,创建索引库,参入参数
 IndexWriter indexWriter = new IndexWriter(directory, config);

 //原始文档的路径
 File dir = new File("D:\\temp\\searchsource");
 
 //循环对dir文件夹下的文件创建索引,dir.listFiles()获得文件夹下所有文件,返回File数组
 for (File f : dir.listFiles()) {
       //文件名
       String fileName = f.getName();
       //文件内容
       String fileContent = FileUtils.readFileToString(f);
       //文件路径
       String filePath = f.getPath();
       //文件的大小
       long fileSize  = FileUtils.sizeOf(f);
       //创建document对象,相当于数据库的表
       Document document = new Document();
               //创建文件名域
        //第一个参数:域的名称
        //第二个参数:域的内容
        //第三个参数:是否存储
        Field fileNameField = new TextField("filename", fileName, Field.Store.YES);
        //文件内容域
        Field fileContentField = new TextField("content", fileContent, Field.Store.YES);
        //文件路径域(不分析、不索引、只存储)
        Field filePathField = new TextField("path", filePath, Field.Store.YES);
        //文件大小域
        Field fileSizeField = new TextField("size", fileSize + "", Field.Store.YES);
        //加入document
        document.add(fileNameField);
        document.add(fileContentField);
        document.add(filePathField);
        document.add(fileSizeField);
        //创建索引,并写入索引库
        indexWriter.addDocument(document);
 }
  //关闭indexwriter
  indexWriter.close();
  1. 分词器

Standard(默认)

Standard在分词时,按照空格分开,把所有大写改成小写,如a ,and这些无意义的会设置成停用词,中文会把每个字都分成一个

IKAnalyzer(中文分词器)

按照中文词汇进行分词

  //在创建IndexWriterConfig ,传入指定分词器
  IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
  1. 索引库的crud
  • 添加
    //索引库存放路径
    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //创建一个indexwriter对象
    IndexWriter indexWriter = new IndexWriter(directory, config);
    //创建一个Document对象
    Document document = new Document();
    //向document对象中添加域。
    //不同的document可以有不同的域,同一个document可以有相同的域。
    document.add(new TextField("filename", "新添加的文档", Field.Store.YES));
    document.add(new TextField("content", "新添加的文档的内容", Field.Store.NO));
    //LongPoint创建索引
    document.add(new LongPoint("size", 1000l));
    //StoreField存储数据
    document.add(new StoredField("size", 1000l));
    //不需要创建索引的就使用StoreField存储
    document.add(new StoredField("path", "d:/temp/1.txt"));
    //添加文档到索引库
    indexWriter.addDocument(document);
    //关闭indexwriter
    indexWriter.close();
  • 删除
    //索引库存放路径
    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //创建一个indexwriter对象
    IndexWriter indexWriter = new IndexWriter(directory, config);
	//删除全部索引
    indexWriter.deleteAll();
	//关闭indexwriter
	indexWriter.close();

	//删除全部索引
	indexWriter.deleteAll();
	//关闭indexwriter
	indexWriter.close();

    //指定条件删除
	IndexWriter indexWriter = getIndexWriter();
	//创建一个查询条件
	Query query = new TermQuery(new Term("filename", "apache"));
	//根据查询条件删除
	indexWriter.deleteDocuments(query);
	//关闭indexwriter
	indexWriter.close();
  • 修改
    lucene修改原理是先删除,在添加
    //索引库存放路径
    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //创建一个indexwriter对象
    IndexWriter indexWriter = new IndexWriter(directory, config);
    //创建一个Document对象
    Document document = new Document();
    //向document对象中添加域。
    //不同的document可以有不同的域,同一个document可以有相同的域。
    document.add(new TextField("filename", "要更新的文档", Field.Store.YES));
    document.add(new TextField("content", " Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包," +
                                                       "它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。",
                Field.Store.YES));
    indexWriter.updateDocument(new Term("content", "java"), document);
    //关闭indexWriter
    indexWriter.close();
  • 查询

TermQuery

TermQuery,通过项查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。
指定要查询的域和要查询的关键词。

    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
    //创建查询对象
    Query query = new TermQuery(new Term("content", "lucene"));
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    //共查询到的document个数
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    //遍历查询结果
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("filename"));
        //System.out.println(document.get("content"));
        System.out.println(document.get("path"));
        System.out.println(document.get("size"));
    }
    //关闭indexreader
    indexSearcher.getIndexReader().close();

数值范围查询

    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    //读取
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建查询对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //指定查询
    Query query = LongPoint.newRangeQuery("size", 0l, 10000l);
    //执行查询
    printResult(query, indexSearcher);

使用queryparser查询

通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。
需要使用到分析器。

    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
    //创建queryparser对象
    //第一个参数默认搜索的域
    //第二个参数就是分析器对象
    QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
    Query query = queryParser.parse("Lucene是java开发的");
    //执行查询
    printResult(query, indexSearcher);
}

private void printResult(Query query, IndexSearcher indexSearcher) throws Exception {
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    //共查询到的document个数
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    //遍历查询结果
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("filename"));
        //System.out.println(document.get("content"));
        System.out.println(document.get("path"));
        System.out.println(document.get("size"));
    }
    //关闭indexreader
    indexSearcher.getIndexReader().close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值