删除索引(文档)

需求

某些图书不再出版销售了,我们需要从索引库中移除该图书。

 1 @Test
2 public void deleteIndex() throws Exception {
3 // 1、指定索引库目录
4 Directory directory = FSDirectory.open(new File("F:\\lucene\\0719"));
5 // 2、创建IndexWriterConfig
6 IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST,
7 new StandardAnalyzer());
8 // 3、 创建IndexWriter
9 IndexWriter writer = new IndexWriter(directory, cfg);
10 // 4、通过IndexWriter来删除索引
11 // 删除指定索引
12 writer.deleteDocuments(new Term("name", "apache"));
13 // 5、关闭IndexWriter
14 writer.close();
15
16 System.out.println("删除成功");
17
18 }

清空索引库

 1 @Test
2 public void deleteIndex() throws Exception {
3 // 1、指定索引库目录
4 Directory directory = FSDirectory.open(new File("F:\\lucene\\0719"));
5 // 2、创建IndexWriterConfig
6 IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST,
7 new StandardAnalyzer());
8 // 3、 创建IndexWriter
9 IndexWriter writer = new IndexWriter(directory, cfg);
10 // 4、通过IndexWriter来删除索引
11 // 删除指定索引
12 writer.deleteAll();
13 // 5、关闭IndexWriter
14 writer.close();
15
16 System.out.println("清空索引库成功");
17
18 }

更新索引(文档)

Lucene更新索引比较特殊,是先删除满足条件的索引,再添加新的索引。

 1 @Test
2 public void updateIndex() throws Exception {
3 // 1、指定索引库目录
4 Directory directory = FSDirectory.open(new File("F:\\lucene\\0719"));
5 // 2、创建IndexWriterConfig
6 IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST,
7 new StandardAnalyzer());
8 // 3、 创建IndexWriter
9 IndexWriter writer = new IndexWriter(directory, cfg);
10 // 4、通过IndexWriter来修改索引
11 // a)、创建修改后的文档对象
12 Document document = new Document();
13
14 // 文件名称
15 Field filenameField = new StringField("name", "updateIndex", Store.YES);
16 document.add(filenameField);
17
18 // 修改指定索引为新的索引
19 writer.updateDocument(new Term("name", "apache"), document);
20
21 // 5、关闭IndexWriter
22 writer.close();
23
24 System.out.println("更新成功");
25 }

已经知道Lucene是通过IndexSearcher对象,来执行搜索的。那我们为什么还要继续学习Lucene呢?

答:因为在实际的开发中,我们的查询的业务是相对复杂的,比如我们在通过关键词查找的时候,往往进行价格、商品类别的过滤。

而Lucene提供了一套查询方案,供我们实现复杂的查询。

-------------------------------------------------------------------------------------------------------------------------------

创建查询的两种方法

执行查询之前,必须创建一个查询Query查询对象。

Query自身是一个抽象类,不能实例化,必须通过其它的方式来实现初始化。

在这里,Lucene提供了两种初始化Query查询对象的方式。

使用Lucene提供Query子类

Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。

使用TermQuery实例化

Query query = new TermQuery(new Term("name", "lucene"));

使用QueryParse解析查询表达式

QueryParser queryParser = new QueryParser("name", new IKAnalyzer());

Query query = queryParser.parse("name:lucene");

常用的Query子类搜索

TermQuery

特点:查询的关键词不会再做分词处理,作为整体来搜索。代码如下:

 1 /**
2 * Query子类查询之 TermQuery
3 *
4 * 特点:不会再对查询的关键词做分词处理。
5 *
6 * 需要:查询书名与java教程相关书。
7 */
8 @Test
9 public void queryByTermQuery(){
10 //1、获取一个查询对象
11 Query query = new TermQuery(new Term("name", "编程思想"));
12 doSearch(query);
13
14 }
15 private void doSearch(Query query) {
16 try {
17
18
19 //2、创建一个查询的执行对象
20 //指定索引库的目录
21 Directory d = FSDirectory.open(new File("F:\\lucene\\0719"));
22 //创建流对象
23 IndexReader reader = DirectoryReader.open(d);
24 //创建搜索执行对象
25 IndexSearcher searcher = new IndexSearcher(reader);
26
27 //3、执行搜索
28 TopDocs result = searcher.search(query, 10);
29
30 //4、提出结果集,获取图书的信息
31 int totalHits = result.totalHits;
32 System.out.println("共查询到"+totalHits+"条满足条件的数据!");
33 System.out.println("-----------------------------------------");
34 //提取图书信息。
35 //score即相关度。即搜索的关键词和 图书名称的相关度,用来做排序处理
36 ScoreDoc[] scoreDocs = result.scoreDocs;
37
38 for (ScoreDoc scoreDoc : scoreDocs) {
39 /**
40 * scoreDoc.doc的返回值,是文档的id, 即 将文档写入索引库的时候,lucene自动给这份文档做的一个编号。
41 *
42 * 获取到这个文档id之后,即可以根据这个id,找到这份文档。
43 */
44 int docId = scoreDoc.doc;
45 System.out.println("文档在索引库中的编号:"+docId);
46
47 //从文档中提取图书的信息
48 Document doc = searcher.doc(docId);
49 System.out.println("图书id:"+doc.get("id"));
50 System.out.println("图书name:"+doc.get("name"));
51 System.out.println("图书price:"+doc.get("price"));
52 System.out.println("图书pic:"+doc.get("pic"));
53 System.out.println("图书description:"+doc.get("description"));
54 System.out.println();
55 System.out.println("------------------------------------");
56
57 }
58
59 //关闭连接,释放资源
60 if(null!=reader){
61 reader.close();
62 }
63 } catch (Exception e) {
64 e.printStackTrace();
65 }
66 }

NumericRangeQuery

指定数字范围查询.(创建field类型时,注意与之对应)

 1 /**
2 * Query子类查询 之 NumricRangeQuery
3 * 需求:查询所有价格在[60,80)之间的书
4 * @param query
5 */
6 @Test
7 public void queryByNumricRangeQuery(){
8 /**
9 * 第一个参数:要搜索的域
10 * 第二个参数:最小值
11 * 第三个参数:最大值
12 * 第四个参数:是否包含最小值
13 * 第五个参数:是否包含最大值
14 */
15 Query query = NumericRangeQuery.newFloatRange("price", 60.0f, 80.0f, true, false);
16
17 doSearch(query);
18 }

BooleanQuery

BooleanQuery,布尔查询,实现组合条件查询。

 1 /**
2 * Query子类查询 之 BooelanQuery查询 组合条件查询
3 *
4 * 需求:查询书名包含java,并且价格区间在[60,80)之间的书。
5 */
6 @Test
7 public void queryBooleanQuery(){
8 //1、要使用BooelanQuery查询,首先要把单个创建出来,然后再通过BooelanQuery组合
9 Query price = NumericRangeQuery.newFloatRange("price", 60.0f, 80.0f, true, false);
10 Query name = new TermQuery(new Term("name", "java"));
11
12 //2、创建BooleanQuery实例对象
13 BooleanQuery query = new BooleanQuery();
14 query.add(name, Occur.MUST_NOT);
15 query.add(price, Occur.MUST);
16 /**
17 * MSUT 表示必须满足 对应的是 +
18 * MSUT_NOT 必须不满足 应对的是 -
19 * SHOULD 可以满足也可以不满足 没有符号
20 *
21 * SHOULD 与MUST、MUST_NOT组合的时候,SHOULD就没有意义了。
22 */
23
24 doSearch(query);
25 }

通过QueryParser搜索

特点

对搜索的关键词,做分词处理。

语法

基础语法

域名:关键字

实例:name:java

组合条件语法

条件1 AND 条件2

条件1 OR 条件2

条件1 NOT 条件2

QueryParser

 1 /**
2 * 查询解析器查询 之 QueryParser查询
3 */
4 @Test
5 public void queryByQueryParser(){
6 try {
7
8 //1、加载分词器
9 Analyzer analyzer = new StandardAnalyzer();
10
11 /**
12 * 2、创建查询解析器实例对象
13 * 第一个参数:默认搜索的域。
14 * 如果在搜索的时候,没有特别指定搜索的域,则按照默认的域进行搜索
15 * 如何在搜索的时候指定搜索域呢?
16 * 答:格式 域名:关键词 即 name:java教程
17 *
18 * 第二个参数:分词器 ,对关键词做分词处理
19 */
20 QueryParser parser = new QueryParser("description", analyzer);
21
22 Query query = parser.parse("name:java教程");
23
24 doSearch(query);
25
26 } catch (Exception e) {
27 e.printStackTrace();
28 }
29 }

MultiFieldQueryParser

通过MulitFieldQueryParse对多个域查询。

 1 /**
2 * 查询解析器查询 之 MultiFieldQueryParser查询
3 *
4 * 特点:同时指定多个搜索域,并且对关键做分词处理
5 */
6 @Test
7 public void queryByMultiFieldQueryParser(){
8 try {
9
10 //1、定义多个搜索的 name、description
11 String[] fields = {"name","description"};
12 //2、加载分词器
13 Analyzer analyzer = new StandardAnalyzer();
14
15 //3、创建 MultiFieldQueryParser实例对象
16 MultiFieldQueryParser mParser = new MultiFieldQueryParser(fields, analyzer);
17
18 Query query = mParser.parse("lucene教程");
19
20 doSearch(query);
21 } catch (Exception e) {
22 e.printStackTrace();
23 }
24 }

中文分词器

什么是中文分词器

学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开

而中文的语义比较特殊,很难像英文那样,一个汉字一个汉字来划分。

所以需要一个能自动识别中文语义的分词器

使用中文分词器IKAnalyzer

添加jar包

修改分词器代码

1 / 创建中文分词器
2 Analyzer analyzer = new IKAnalyzer();

思考?

在一堆文件中,如何快速根据关键词找出对应的文件?

思路:(1)使用全文检索来解决问题

(2)数据源由数据库变成一堆文件。

(3)从一堆文件中,读出里面的内容,转成文档,创建索引库。

(4)创建索引库之后,再根据关键词搜索索引库,找出文件的名称。

问题:如何读文件的内容?

答:txt文本,直接使用IO即可。

doc|docx  使用POI读取内容。

Lucene索引库维护、搜索、中文分词器的更多相关文章

  1. Lucene全文检索_分词_复杂搜索_中文分词器

    1 Lucene简介 Lucene是apache下的一个开源的全文检索引擎工具包. 1.1 全文检索(Full-text Search)  1.1.1 定义 全文检索就是先分词创建索引,再执行搜索的过 ...

  2. Lucene全文搜索之分词器:使用IK Analyzer中文分词器(修改IK Analyzer源码使其支持lucene5.5.x)

    注意:基于lucene5.5.x版本 一.简单介绍下IK Analyzer IK Analyzer是linliangyi2007的作品,再此表示感谢,他的博客地址:http://linliangyi2 ...

  3. Elasticsearch的索引模块(正排索引、倒排索引、索引分析模块Analyzer、索引和搜索、停用词、中文分词器)

    正向索引的结构如下: “文档1”的ID > 单词1:出现次数,出现位置列表:单词2:出现次数,出现位置列表:…………. “文档2”的ID > 此文档出现的关键词列表. 一般是通过key,去 ...

  4. 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  5. Lucene的中文分词器

    1 什么是中文分词器 学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开. 而中文的语义比较特殊,很难像英文那样,一个汉字一个汉字来划分. 所以需要一个能自动识别中文语义的分 ...

  6. Lucene 03 - 什么是分词器 + 使用IK中文分词器

    目录 1 分词器概述 1.1 分词器简介 1.2 分词器的使用 1.3 中文分词器 1.3.1 中文分词器简介 1.3.2 Lucene提供的中文分词器 1.3.3 第三方中文分词器 2 IK分词器的 ...

  7. Solr7.1---数据库导入并建立中文分词器

     这里只是告诉你如何导入,生产环境不要这样部署你的solr服务. 首先修改solrConfig.xml文件 备份_default文件夹 修改solrconfig.xml 加入如下内容 官方示例:< ...

  8. (五)Lucene——中文分词器

    1. 什么是中文分词器 对于英文,是安装空格.标点符号进行分词 对于中文,应该安装具体的词来分,中文分词就是将词,切分成一个个有意义的词. 比如:“我的中国人”,分词:我.的.中国.中国人.国人. 2 ...

  9. ElasticSearch7.3学习(十五)----中文分词器(IK Analyzer)及自定义词库

    1. 中文分词器 1.1 默认分词器 先来看看ElasticSearch中默认的standard 分词器,对英文比较友好,但是对于中文来说就是按照字符拆分,不是那么友好. GET /_analyze ...

随机推荐

  1. day03 每日一行

    day03 每日一行 问题描述 用列表解释式 .生成器表达式实现 字典列表为: [{'first': 'john', 'last': 'smith', 'email': 'jsmith@exsampl ...

  2. JavaScript函数的高级用法

    1.函数的定义和调用 1.1函数的定义方式 方式1 函数声明方式 function 关键字 (命名函数) function fn(){} 方式2 函数表达式(匿名函数) var fn = functi ...

  3. istio的安全(概念)

    Istio 安全(概念) 目录 Istio 安全(概念) 高层架构 Istio身份 身份和证书管理 认证 Mutial TLS认证 宽容(Permissive)模式 安全命名 认证架构 认证策略 策略 ...

  4. js区别对象和数组的三种方法

    var arr = {}||[];            区分arr是数组还是对象            1.arr.constructor                              ...

  5. Python的UI库

    https://github.com/realitix/vulkan https://github.com/swistakm/pyimgui https://wxpython.org

  6. 常用mac命令

    ~/.bash_profile 可以添加常用的一些命令别名alias unity="open -n /Applications/Unity/Unity.app"

  7. java初探(1)之登录总结

    登录总结 前几章总结了登录各个步骤中遇到的问题,现在完成的做一个登录的案例,其难点不在于实现功能,而在于抽象各种功能模块,提高复用性,较低耦合度. 前端页面: 对于前端页面来说,不是后端程序员要考虑的 ...

  8. OpenResty 作者章亦春访谈实录

    [软件简介] OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器.它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 通过众多 ...

  9. 06_Python异常处理机制

    1.异常概述 1.什么是错误: 错误是指有逻辑或语法等导致一个程序无法正常执行的问题     2.什么是异常: 异常时程序出错时标识的一种状态,程序不会向下执行而转去调用此函数的地方等待处理错误并恢复 ...

  10. 一文读懂神经网络训练中的Batch Size,Epoch,Iteration

    一文读懂神经网络训练中的Batch Size,Epoch,Iteration 作为在各种神经网络训练时都无法避免的几个名词,本文将全面解析他们的含义和关系. 1. Batch Size 释义:批大小, ...