阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Lucene实践心得笔记

405次阅读
没有评论

共计 6027 个字符,预计需要花费 16 分钟才能阅读完成。

在使用 Lucene 前,我们先大致熟悉下 Lucene 的几个核心类。

核心索引类:

  • public class IndexWriter

索引过程的中心组件,把它想象成一个可以对索引进行写操作的对象。

  • public abstract class Directry

Directory 代表索引所在的位置,该抽象类有两个具体的子类实现。FSDirectory 表示存储在文件系统的索引位置,RAMDirectory 表示存储在内存中的索引位置。

  • public abstract class Analyzer

    分词组件。在建立索引前首先要对文档进行分词,Lucene 默认有一些分词类的实现,自己实现的分词要继承该类。

  • public final class Document

    Document 类似于数据库中的一条记录,它由好几个字段 Field 组成。

  • public final class Field

    Field 用来描述文档的某个属性,例如文章的标题,内容等等。

核心搜索类:

  • public class IndexSeacher

    用来在已经建好的索引上进行搜索操作

  • public final class Term

    搜索的基本单元。Term 对象有两个域组成。Term term = new Term(“fieldName”,”queryWord”);

  • public abstract class Query

    抽象类,有很多具体实现类。该类主要作用把用户输入的查询语句转换为 Lucene 能够是别的 query。

  • public final class Hits(TopDocs)

    Hits 是用来保存查询得到的结果的。最新版的 Lucene 中,TopDocs 已代替了 Hits。

 我们拿一张纸、一支笔,填写下面的表格:

序号

文件名

文件路径

文件类型

文件大小

修改时间

内容

……

               

    填完以后,搜索的时候就可以照着这张纸“按图索骥”了。

    在 lucene 中,这张纸叫做 Directory(也就是索引保存的目录),这支笔叫做 IndexWriter,表格中一条记录叫做 Document,记录中的每项叫做 Field。

 下面我们来看第一个简单的 Lucene 实现索引的例子(Lucene 版本为 4.10.1)。public class LuceneDemo {public static void main(String[] args){//RAMDirectory(内存路径)继承自 Directory 抽象类,另一个继承自该类的是 FSDirectory(文件系统路径),Directory dir = FSDirectory.open(new File("此处写索引存储的位置,"));
        Directory dir = new RAMDirectory();
            
        //SimpleAnalyzer 继承自抽象类 Analyzer,是分词组件,不同语言有不同的分词组件包,也可以自己定义实现该抽象类 
        Analyzer analyzer = new SimpleAnalyzer();
        
        // 定义 IndexWriterConfig
        IndexWriterConfig iwc = new IndexWriterConfig(Version.LATEST, analyzer);
        
        // 定义 document 对象 
        Document doc = new Document();
        
        try {// 第一步,切词入库,创建索引。定义 IndexWriter 对索引进行“写”操作 
            IndexWriter iw = new IndexWriter(dir, iwc);
            
            //Field 对象的构造方法有四个参数,前两个参数表示要建立索引的 name 和 value,name 指索引的名称,value 指要建立索引的“文档对象”,例如博客的标题、正文
            //Field.Store 有 YES 和 NO 两个值,表示是否存储该 Field
            //Field.Index 有 5 个不同的取值,ANALYZED,ANALYZED_NO_NORMS,NOT_ANALYZED,NOT_ANALYZED_NO_NORMS,NO, 根据不同情况选择是否分词 
            doc.add(new Field("title", "james bonde", Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("content","He want to go to school next year.",Field.Store.YES,Field.Index.ANALYZED));
            doc.add(new Field("doc","He will go to his mother's home.",Field.Store.YES,Field.Index.ANALYZED));
            iw.addDocument(doc);
            iw.close();
            
            // 第二步,查询索引,返回结果 
            IndexReader ir = DirectoryReader.open(dir);
            
            // 定义 IndexSearcher
            IndexSearcher is = new IndexSearcher(ir);
            
            // 定义 Term,new Term("doc", "home"),第一个值表示要搜索的域,第二个则表示搜索值 
            Term term = new Term("doc", "home");
            
            //TermQuery 继承自 Query 抽象类,是 Lucene 最基本的查询 
            Query query = new TermQuery(term);
            
            // 执行查询,返回 TopDocs 对象结果集 
            TopDocs td = is.search(query, 10);
            
            for(int i=0;i<td.scoreDocs.length;i++){Document d = is.doc(td.scoreDocs[i].doc);
                System.out.println("----------"+d.getField("title"));
                System.out.println("----------"+d.getField("content"));
                System.out.println("----------"+d.getField("doc"));
            }
            dir.close();} catch (IOException e) {// TODO Auto-generated catch block
            e.printStackTrace();}    
    }

}
 
 索引的创建、修改和删除

首先,我们来看一个例子:开源中国社区每天都有人发布新的博客,同时也有很多人在进行修改和删除博客的操作。如果我们只更新博客数据而不更新对应的索引数据,这会带来那些问题呢?新增的博客信息不能够及时被用户搜索到;修改的博客信息查询时依然显示之前的内容;删除的博客信息查询时存在但实际已被删除。因此,为了提高系统搜索的准确性和实时性,我们在进行数据更新的同时,也会更新与之对应的索引数据,这样业务数据就可以保持与索引数据的一致,上面的几个问题也就随之解决了。首先,我们来看新增索引的操作,这个比较简单,之前的例子里面已经有讲到:// 当新增博客时,索引也增量更新 
public void addLuceneIndex(Blog blog){try {IndexWriter writer = new IndexWriter(directory, config);
        Document doc = new Document();
      
        // 文章 id,需要存储,查询结果的链接需要,但不需要检索 
        doc.add(new Field("id",blog.getString("id"),Field.Store.YES,Field.Index.NO));
      
        // 文章标题,需要存储也需要切词索引 
        doc.add(new Field("title",blog.getString("title"),Field.Store.YES,Field.Index.ANALYZED));
      
        // 文章内容一般会比较长,所以不需要存储,但需要切词索引 
        doc.add(new Field("content",blog.getString("content"),Field.Store.NO,Field.Index.ANALYZED));
      
        // 文章作者,需要存储,整体索引但不切词 
        doc.add(new Field("author",blog.getString("author"),Field.Store.YES,Field.Index.NOT_ANALYZED));
        writer.addDocument(doc);
        writer.forceMerge(1);
        writer.commit();} catch (IOException e) {// TODO Auto-generated catch block
      e.printStackTrace();}
}
当博客被修改时,对应索引也执行更新操作,实际后台代码执行的是先删除再新增操作。// 索引更新操作 
public void updateLuceneIndex(Blog blog){try {IndexWriter writer = new IndexWriter(directory, config);
        Document doc = new Document();
        writer.updateDocument(new Term("id", blog.getString("id")), doc);
        writer.forceMerge(1);
        writer.commit();} catch (IOException e) {// TODO Auto-generated catch block
        e.printStackTrace();}
}
当文章删除时,对应索引也执行删除操作

// 索引删除操作 
public void delLuceneIndex(Blog blog){try {indexWriter.deleteDocuments(new Term("id", blog.getString("id")));  // Document 删除 
    } catch (IOException e) {e.printStackTrace();
    }
}
最后说明一下,索引文件的增、删、改在实际应用过程中也是有很多策略的。比如对于搜索实时性要求比较高的系统,可以采取实时更新的策略,在更新记录时同时更新索引;如果系统对搜索的实时性要求不高,且服务器资源有限,可以设置一个定时任务,把白天更新的记录都标记出来,在凌晨服务器空闲的时候批量更新。总之,可以根据自己的需要去灵活的应用。分词(切词)分词也叫作切词,是指把文档的内容按照一定的规则切分成一个个独立的词语,通俗的说就是把句子切分成词语。分词是影响 Lucene 查询效率和查询准确率的关键因素。所有的分词器都继承自 Lucene 的 Analyzer,今天介绍最流行和通用的中文分词器 IKAnalyzer 的使用。Lucene 默认实现的有英文分词。英文分词相对简单,主要是对每个单词的单复数,时态等做转换即可。而中文分词相对更复杂一些。因为中文的词库本身就非常庞杂,同一个句子可能有好几种分词法,不同的分词法可能就会导致不同的查询结果。IKAnalyzer 为我们解决以上问题提供了很好的方案,它允许我们可以个性化定义扩展词库,而且分词效率极高。下面我们来看下 IKAnalyzer 的配置文件 IKAnalyzer.cfg.xml,把它放置到源文件根目录下面,系统会自动加载进来。<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
    <comment>IKAnalyzer 扩展配置 </comment>
    
    <!-- 用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">
        /com/jfinal/lucene/ext.dic; 
        /com/jfinal/lucene/ft_main2012.dic; 
        /com/jfinal/lucene/ft_quantifier.dic; 
    </entry>
    
    <!-- 用户可以在这里配置自己的扩展停止词字典 -->
    <entry key="ext_stopwords">
        /com/jfinal/lucene/stop.dic
    </entry>
    
</properties>
ext.dic 用来定义自己的扩展词库。比如特定的地名,人名,就相当于告诉分词器如果遇到这些词汇就把它们做单独分词;stop.dic 用来定义自己的扩展停止词字典,停止词就是指那些最普通的,没有特定含义的词。比如英语里面的 a,the,汉语里面的了,又等等。把 IKAnalyzer 的 jar 包拷贝到 lib 下,使用时新建对象即可。Analyzer analyzer = new IKAnalyzer()

————————————– 分割线 ————————————–

基于 Lucene 多索引进行索引和搜索 http://www.linuxidc.com/Linux/2012-05/59757.htm

Lucene 实战 (第 2 版) 中文版 配套源代码 http://www.linuxidc.com/Linux/2013-10/91055.htm

Lucene 实战 (第 2 版) PDF 高清中文版 http://www.linuxidc.com/Linux/2013-10/91052.htm

使用 Lucene-Spatial 实现集成地理位置的全文检索 http://www.linuxidc.com/Linux/2012-02/53117.htm

Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a9 http://www.linuxidc.com/Linux/2012-02/53113.htm

Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a8 http://www.linuxidc.com/Linux/2012-02/53111.htm

Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a7 http://www.linuxidc.com/Linux/2012-02/53110.htm

Project 2-1: 配置 Lucene, 建立 WEB 查询系统 [Ubuntu 10.10] http://www.linuxidc.com/Linux/2010-11/30103.htm

————————————– 分割线 ————————————–

Lucene 的详细介绍 :请点这里
Lucene 的下载地址 :请点这里 

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-03/141902.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计6027字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19350
评论数
4
阅读量
7960710
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛 NAS-12:开源笔记的进化之路,效率玩家的新选择 前言 如何高效管理知识与笔记,已经成为技术...
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个 AI 智能体 — 跟创业大佬对话 前言 智能体(Agent)已经成为创业者和技术人绕...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级 大家好,我是星哥,之前写了一篇文章 自己手撸一...
你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你 为什么要用宝塔跑分? 宝塔跑分其实就是对 CPU、内存、磁盘、IO 做...
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

  240 元左右!五盘位 NAS 主机,7 代 U 硬解 4K 稳如狗,拓展性碾压同价位 在 NA...