(四)Lucene——搜索和相关度排序
1. 搜索
1.1 创建查询对象的方式
- 通过Query子类来创建查询对象
Query子类常用的有:TermQuery、NumericRangeQuery、BooleanQuery
特点:不能输入lucene的查询语法,不需要指定分词器
- 通过QueryParser来创建查询对象(常用)
QueryParser、MultiFieldQueryParser
特点:可以输入lucene的查询语法、可以指定分词器
1.2 通过Query子类来创建查询对象
1.2.1 TermQuery(精确的词项查询)
@Test
public void termQuery() {
// 创建TermQuery对象
Query query = new TermQuery(new Term("description", "java"));
doSearch(query);
}
private void doSearch(Query query) {
// 创建IndexSearcher
// 指定索引库的地址
try {
File indexFile = new File("D:\\DBIndex\\");
Directory directory = FSDirectory.open(indexFile);
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
// 通过searcher来搜索索引库
// 第二个参数:指定需要显示的顶部记录的N条
TopDocs topDocs = searcher.search(query, 10);
// 根据查询条件匹配出的记录总数
int count = topDocs.totalHits;
System.out.println("匹配出的记录总数:" + count);
// 根据查询条件匹配出的记录
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
// 获取文档的ID
int docId = scoreDoc.doc;
// 通过ID获取文档
Document doc = searcher.doc(docId);
System.out.println("商品ID:" + doc.get("id"));
System.out.println("商品名称:" + doc.get("name"));
System.out.println("商品价格:" + doc.get("price"));
System.out.println("商品图片地址:" + doc.get("pic"));
System.out.println("==========================");
// System.out.println("商品描述:" + doc.get("description"));
}
// 关闭资源
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
1.2.2 NumericRangeQuery(数字范围查询)
@Test
public void numericRangeQuery() {
// 创建NumericRangeQuery对象
// 参数:域的名称、最小值、最大值、是否包含最小值、是否包含最大值
Query query = NumericRangeQuery.newFloatRange("price", 55f, 60f, true, false);
doSearch(query);
}
1.2.3 BooleanQuery(组合查询)
@Test
public void booleanQuery() {
// 创建BooleanQuery
BooleanQuery query = new BooleanQuery();
// 创建TermQuery对象
Query q1 = new TermQuery(new Term("description", "lucene"));
// 创建NumericRangeQuery对象
// 参数:域的名称、最小值、最大值、是否包含最小值、是否包含最大值
Query q2 = NumericRangeQuery.newFloatRange("price", 55f, 60f, true, false); // 组合关系代表的意思如下:
// 1、MUST和MUST表示“与”的关系,即“交集”。
// 2、MUST和MUST_NOT前者包含后者不包含。
// 3、MUST_NOT和MUST_NOT没意义
// 4、SHOULD与MUST表示MUST,SHOULD失去意义;
// 5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。
// 6、SHOULD与SHOULD表示“或”的概念。 query.add(q1, Occur.MUST_NOT);
query.add(q2, Occur.MUST_NOT); doSearch(query);
}
1.3 通过QueryParser来创建查询对象
1.3.1 QueryParser
通过QueryParser来创建query对象,可以指定分词器,搜索时的分词器和创建该索引的分词器一定要一致。还可以输入查询语句。
@Test
public void indexSearch() throws Exception {
// 创建query对象
// 使用QueryParser搜索时,需要指定分词器,搜索时的分词器要和索引时的分词器一致
// 第一个参数:默认搜索的域的名称
QueryParser parser = new QueryParser("description", new StandardAnalyzer()); // 通过queryparser来创建query对象
// 参数:输入的lucene的查询语句(关键字一定要大写)
Query query = parser.parse("description:java AND lucene"); doSearch(query);
}
1.3.2 MultiFieldQueryParser(多域查询)
@Test
public void multiFieldQueryParser() throws Exception {
// 创建 MultiFieldQueryParser
// 默认搜索的多个域的域名
String[] fields = { "name", "description" };
Analyzer analyzer = new StandardAnalyzer();
Map<String, Float> boosts = new HashMap<String, Float>();
boosts.put("name", 200f);
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer, boosts); // Query query = parser.parse("name:lucene OR description:lucene");
Query query = parser.parse("java");
System.out.println(query); doSearch(query);
}
1.3.3 查询语法
(1)基础的查询语法,关键词查询
域名+“:”+搜索的关键字
例如:content:java
(2)范围查询
域名+“:”+[最小值 TO 最大值]
例如:size:[1 TO 1000]
注意:QueryParser不支持对数字范围的搜索,它支持字符串范围。数字范围搜索建议使用NumericRangeQuery。
(3)组合条件查询
|
Occur.MUST 查询条件必须满足,相当于and |
+(加号) |
|
Occur.SHOULD 查询条件可选,相当于or |
空(不用符号) |
|
Occur.MUST_NOT 查询条件不能满足,相当于not非 |
-(减号) |
(3.1)+条件1 +条件2:两个条件之间是并且的关系and
例如:+filename:apache +content:apache
(3.2)+条件1 条件2:必须满足第一个条件,忽略第二个条件
例如:+filename:apache content:apache
(3.3)条件1 条件2:两个条件满足其一即可。
例如:filename:apache content:apache
(3.4)-条件1 条件2:必须不满足条件1,要满足条件2
例如:-filename:apache content:apache
(4)组合查询(3)的第二种写法
- 条件1 AND 条件2
- 条件1 OR 条件2
- 条件1 NOT 条件2
1.4 TopDocs
Lucene搜索结果可通过TopDocs遍历,TopDocs类提供了少量的属性,如下:
|
方法或属性 |
说明 |
|
totalHits |
匹配搜索条件的总记录数 |
|
scoreDocs |
顶部匹配记录 |
注意:
Search方法需要指定匹配记录数量n:indexSearcher.search(query, n)
TopDocs.totalHits:是匹配索引库中所有记录的数量
TopDocs.scoreDocs:匹配相关度高的前边记录数组,scoreDocs的长度小于等于search方法指定的参数n
2. 相关度排序
2.1 什么是相关度排序
相关度排序就是查询关键字与查询结果的匹配相关度。匹配越高的越靠前。Lucene是通过打分来进行相关度排序的。
2.1.1 打分分两步:
step1:根据词计算词的权重
step2:根据词的权重进行打分
2.1.2 词的权重
词指的就是term。也就是说一个term对一个文档的重要性,就叫词的权重。
影响词的权重的方式有两种:
- Tf ——词在同一个文档中出现的频率
Tf越高,说明词的权重越高
- Df ——词在多个文档中出现的频率
Df越高,说明词的权重越低
以上是自然打分的规则。
2.2 设置boost值影响打分
Boost:加权值,默认是1.0f。
设置加权值可以在创建索引时(如下代码)设置,也可以在查询时(见1.3.2 MultiFieldQueryParser(多域查询))设置。
for (Book book : list) {
document = new Document();
// store:如果是yes,则说明存储到文档域中
// 图书ID
// 不分词、索引、存储 StringField
Field id = new StringField("id", book.getId().toString(), Store.YES);
// 图书名称
// 分词、索引、存储 TextField
Field name = new TextField("name", book.getName(), Store.YES);
············
// 设置boost值
if (book.getId() == 4)
description.setBoost(100f);
// 将field域设置到Document对象中
document.add(id);
·············
}
Boost值是设置到Field域上的。
(四)Lucene——搜索和相关度排序的更多相关文章
- Lucene 08 - 什么是Lucene的相关度排序 + Java API调整相关度
目录 1 什么是相关度 2 相关度评分 3 相关度设置 3.1 更改相关度的需求 3.2 实现需求-设置广告 1 什么是相关度 概念: 相关度指两个事物之间的关联关系(相关性). Lucene中指的是 ...
- Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)
原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer anal ...
- Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)
原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察 ...
- Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)
原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此 ...
- Lucene搜索方式大合集
package junit; import java.io.File; import java.io.IOException; import java.text.ParseException; imp ...
- lucene 搜索demo
package com.ljq.utils; import java.io.File; import java.util.ArrayList; import java.util.List; impor ...
- Lucene学习总结之七:Lucene搜索过程解析
一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...
- Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)
一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...
- Lucene学习总结之七:Lucene搜索过程解析 2014-06-25 14:23 863人阅读 评论(1) 收藏
一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...
随机推荐
- [BZOJ4836]二元运算(分治FFT)
4836: [Lydsy1704月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 578 Solved: 202[Submit][Stat ...
- 实验四 Android程序设计-5
点击button按钮,进入下一活动,"the third activity"
- MySQL中变量的定义和变量的赋值使用(转)
说明:现在市面上定义变量的教程和书籍基本都放在存储过程上说明,但是存储过程上变量只能作用于begin...end块中,而普通的变量定义和使用都说的比较少,针对此类问题只能在官方文档中才能找到讲解. 前 ...
- 用js给循环的列表添加click事件
纠结了两天终于搞定了,首先id这个东西必不可少,这个时候不能用onclik事件,而是需要使用代理事件. 比如说,这里有个列表如下: <ul> <li></li> & ...
- while an existing transition or presentation is occurring; the navigation stack will not be updated
使用UIAlertController提示信息,在之后使用navigation进行逻辑跳转时,出现popToViewController:transition: called on <UINav ...
- linux图机界面机制
1.X WindowX Window 是由麻省理工学院(MIT)推出的窗口系统,简称X,它旨在建立不依赖于特定硬件系统的图形和文字显示窗口系统的标准.1987 年9 月,MIT 推出了X 系统的11 ...
- C语言基本数据类型简介
1.概述 C 语言包含的数据类型如下图所示: 2.各种数据类型介绍 2.1整型 整形包括短整型.整形和长整形. 2.1.1短整形 short a=1; 2.1.2整形 一般占4个字节(32位),最高位 ...
- Linux下的基础命令
在容器环境中很多时候要确定底层操作系统是什么和什么版本,网上找了一把,发现了一些比较有用的命令,从其他地方转过来,参考 # uname -a # 查看内核/操作系统/CPU信息 # head -n / ...
- wireshark常用错误提示分析-转
1.[Packet size limited during capture] 当你看到这个提示,说明被标记的那个包没有抓全.以图1的4号包为例,它全长有171字节,但只有前96个字节被抓到了,因此Wi ...
- 【好】strong-password-checker,我自己做出来的:)
我自己做出来的,分了几种情况来考虑.(再后面有加了注释的版本) https://leetcode.com/problems/strong-password-checker/ // 加油! public ...