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——搜索和相关度排序的更多相关文章

  1. Lucene 08 - 什么是Lucene的相关度排序 + Java API调整相关度

    目录 1 什么是相关度 2 相关度评分 3 相关度设置 3.1 更改相关度的需求 3.2 实现需求-设置广告 1 什么是相关度 概念: 相关度指两个事物之间的关联关系(相关性). Lucene中指的是 ...

  2. Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer anal ...

  3. Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察 ...

  4. Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此 ...

  5. Lucene搜索方式大合集

    package junit; import java.io.File; import java.io.IOException; import java.text.ParseException; imp ...

  6. lucene 搜索demo

    package com.ljq.utils; import java.io.File; import java.util.ArrayList; import java.util.List; impor ...

  7. Lucene学习总结之七:Lucene搜索过程解析

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

  8. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...

  9. Lucene学习总结之七:Lucene搜索过程解析 2014-06-25 14:23 863人阅读 评论(1) 收藏

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

随机推荐

  1. 【构造】Gym - 101411F - Figure ans Spots

    在最外围的一圈没有意义,所以全都涂黑,内部贪心地涂成棋盘即可. #include<cstdio> #include<cstring> using namespace std; ...

  2. [JZOJ3484]密码

    题目大意: 给你一个很长的字符串a(|a|<=300000),一个比较短的字符串b(|b|<=200),请你搞一些破坏. 你可以从a的两边去掉一些字符使得b仍是a的一个字串,问有多少种方案 ...

  3. JS小游戏寻找房祖名

    提示:1:先把两个图片放到重命名并放到相应的路径内. 2:本小游戏只为闲事练手,如有小bug自行解决,解决不了的可以留言,我看到后解决. 代码如下: <!DOCTYPE html>< ...

  4. javascript实现原生ajax

    自从javascript有了各种框架之后,比如jquery,使用ajax已经变的相当简单了.但有时候为了追求简洁,可能项目中不需要加载jquery这种庞大的js插件.但又要使用到ajax这种功能该如何 ...

  5. svn: None of the environment variables SVN_EDITOR...问题解决

    转:http://blog.163.com/lgh_2002/blog/static/44017526201046111856208/ 问题1: svn: Could not use external ...

  6. postgres10配置huge_pages

    操作系统 修改/boot/grub2/grub.cfg 定位到第一个'menuentry 'CentOS Linux',在"linux16 /vmlinuz"最后面添加 numa= ...

  7. xpages开发的bom管理系统

    domino对流程设计是方便的.假设制作复杂逻辑的应用就难了.可是还是能够实现的,曾经的一个bom管理系统.刚開始想使用java的ssh来做,后来为了统一平台.还是使用domino来做,经过长时间的研 ...

  8. [转] SQL SERVER拼接字符串(字符串中有变量)

    本文转自:http://blog.csdn.net/sikaiyuan2008/article/details/7848926 SQL SERVER拼接字符串(字符串中有变量)对我来说是一个难点,总是 ...

  9. iOS:关于UIView切角的两种实现方式

    转载自:http://www.jianshu.com/p/451b7fa94e2a 第一种: 我想你一见到代码,就瞬间有吐的冲动,最常用的一种方式... UIButton *button = [[UI ...

  10. WebService基于SoapHeader实现安全认证[webservice][.net][安全][soapheader]

    摘 自: http://blog.sina.com.cn/s/blog_72b7a82d0100yyp8.html WebService基于SoapHeader实现安全认证[webservice][. ...