lucene 初探 - 查询
lucene初探, 是为了后面solr做准备的. 如果跳过lucene, 直接去看solr, 估计有点懵.
由于时间的关系, lucene查询方法也有多个, 所以单独出来.
一. 精确查询
/**
* 获取 查找对象
* @return
* @throws Exception
*/
private IndexSearcher getSearcher() throws Exception {
//1. 创建一个directory对象, 也就是索引库存放的位置
Directory directory = FSDirectory.open(new File(indexDir)); //2. 创建一个indexReader对象, 需要指定directory
IndexReader indexReader = DirectoryReader.open(directory); //3. 创建一个indexSearcher对象, 需要指定indexReader对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader); return indexSearcher;
} /**
* 输出信息到控制台
* @param indexSearcher
* @param query
* @throws Exception
*/
public void sout(IndexSearcher indexSearcher, Query query) throws Exception {
//5. 执行查询
TopDocs topDocs = indexSearcher.search(query, 5); //6. 返回查询结果
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
//获取文档id
int doc = scoreDoc.doc;
//根据文档id获取文档
Document document = indexSearcher.doc(doc);
//文件名字
String fileName = document.get("fileName");
//文件大小
String fileSize = document.get("fileSize");
//文件路径
String filePath = document.get("filePath");
//文件内容
String fileContent = document.get("fileContent"); System.out.println("fileName : " + fileName);
System.out.println("fileSize : " + fileSize);
System.out.println("filePath : " + filePath);
System.out.println("fileContent : " + fileContent);
System.out.println("-----------------------");
}
} /**
* 精确查询
*
* @throws Exception
*/
@Test
public void searchIndex() throws Exception { //1. 获取查询对象
IndexSearcher indexSearcher = getSearcher(); //2. 创建一个TermQuery对象, 指定查询的域和查询的关键词
Query query = new TermQuery(new Term("fileName", "生活")); sout(indexSearcher, query); //3. 关闭IndexReader 对象
indexSearcher.getIndexReader().close();
}
在查询的时候, 新建一个Term对象, 进去精确匹配. 前一篇提到过, 经过分词器分下来的每一个词或者一段话, 就是一个Term.
这里在新建Term的时候, 传入的是 域名 和 要搜索的词.
这里, 一个Term对象, 只有一个域, 那如果我想查询多个域怎么办呢.
二. 组合查询
/**
* 组合查询
*/
@Test
public void queryBoolean() throws Exception {
IndexSearcher searcher = getSearcher(); BooleanQuery query = new BooleanQuery(); Query query1 = new TermQuery(new Term("fileName", "生活"));
Query query2 = new TermQuery(new Term("fileContent", "生活")); query.add(query1, BooleanClause.Occur.MUST);
query.add(query2, BooleanClause.Occur.SHOULD); //System.out.println(query); sout(searcher, query); searcher.getIndexReader().close();
}
这里的Occur枚举值, 有三个, must, should, must_not .
must : 相当于sql里面的 and 连接
should : 相当于 or , 可有可没有
must_not : 相当于 != , 不包含
这里如果打印query, 会显示: +fileName:生活 fileContent:生活
这是lucene的一种语法, lucene可以根据语法来查询数据. 后面会提到. 如果是must_not , 则使用减号.
如: 将上面的query2使用 MUST_NOT 连接, 则显示成: +fileName:生活 -fileContent:生活
三 . 查询所有
一般查询数据库的时候, 都会提供一个 getAll 方法, 用于查询满足条件的所有数据, 当不传条件时, 就查询所有
lucene也提供了一个查询所有的方法 : MatchAllDocsQuery
/**
* 查询所有
*
* @throws Exception
*/
@Test
public void queryAll() throws Exception {
IndexSearcher searcher = getSearcher(); Query query = new MatchAllDocsQuery(); sout(searcher, query); searcher.getIndexReader().close();
}
四. 数值区间查询
/**
* 数值区间查询
*
* @throws Exception
*/
@Test
public void queryNumericRange() throws Exception {
IndexSearcher searcher = getSearcher(); Query query = NumericRangeQuery.newLongRange("fileSize", 10L, 647L, true, true); sout(searcher, query); searcher.getIndexReader().close();
}
这里的语法输出就是 : fileSize:[40 to 647]
这是因为我后面两个都设置为true, 表示包含关系. 如果都设置为false, 就是 {40 to 647}
五. 分词器解析查询
如前面提到的, 我输入一句话查询, 结果展示的结果却并不是按照我输入的全匹配结果.
那是因为在查询之前, 对输入的信息, 进行了分词器解析, 然后根据解析结果, 再去查询数据.
/**
* 条件解析对象查询
*
* @throws Exception
*/
@Test
public void queryParser() throws Exception { IndexSearcher searcher = getSearcher(); QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer()); //Query query = queryParser.parse("*:*");
Query query = queryParser.parse("fileName:这花好漂亮");
//Query query = queryParser.parse("花"); sout(searcher, query); searcher.getIndexReader().close();
}
*:* 表示查询所有. 不管是哪个域.
fileName:这花好漂亮 : 表示在fileName域中, 将 "这花好漂亮" 分词解析后, 进行查询
花 : 在fileName域中, 查询花. 因为在QueryParse创建的时候, 指定了域为 fileName
即使我在QueryParser里面指定了要查询的域, 但是在parse的时候, 我可以重新指定域.
这里需要注意的是, 在上面数值区间查询的时候, 如果我直接写语法进去查询, 是查不出来的. 因为数值类型变了. 通过语法输进去, 变成字符串类型了.
从结果中可以看到, 我输入 这花好漂亮, 查出来的却是 军中绿花. 这就是分词的作用了.
六. 多域分词查询
/**
* 条件解析对象查询
*
* @throws Exception
*/
@Test
public void queryMultiParser() throws Exception { IndexSearcher searcher = getSearcher(); String[] fields = {"fileName", "fileContent"};
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer()); Query query = queryParser.parse("生活大爆炸"); sout(searcher, query); searcher.getIndexReader().close();
}
多域分词查询, 没啥好说的了.
lucene 初探 - 查询的更多相关文章
- lucene 初探
前言: window文件管理右上角, 有个搜索功能, 可以根据文件名进行搜索. 那如果从文件名上判断不出内容, 我岂不是要一个一个的打开文件, 查看文件的内容, 去判断是否是我要的文件? 几个, 十几 ...
- Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser
一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...
- Hibernate Search集与lucene分词查询
lucene分词查询参考信息:https://blog.csdn.net/dm_vincent/article/details/40707857
- Lucene的查询语法,JavaCC及QueryParser(1)
http://www.cnblogs.com/forfuture1978/archive/2010/05/08/1730200.html 一.Lucene的查询语法 Lucene所支持的查询语法可见h ...
- Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser 2014-06-25 14:25 722人阅读 评论(1) 收藏
一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...
- 全文检索Lucene框架---查询索引
一. Lucene索引库查询 对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name ...
- 【手把手教你全文检索】Apache Lucene初探
PS: 苦学一周全文检索,由原来的搜索小白,到初次涉猎,感觉每门技术都博大精深,其中精髓亦是不可一日而语.那小博猪就简单介绍一下这一周的学习历程,仅供各位程序猿们参考,这其中不涉及任何私密话题,因此也 ...
- [转载] Apache Lucene初探
转载自http://www.cnblogs.com/xing901022/p/3933675.html 讲解之前,先来分享一些资料 首先呢,学习任何一门新的亦或是旧的开源技术,百度其中一二是最简单的办 ...
- 【手把手教你全文检索】Apache Lucene初探 (zhuan)
http://www.cnblogs.com/xing901022/p/3933675.html *************************************************** ...
随机推荐
- DeepFace和GAN
由于换脸技术的影响,现在造假视频的成本越来越低.AI换脸视频也越来越热门,甚至有一些已经达到了以假乱真的程度.虽然有明星反对表示无奈,可是.... 据报道,2018年,arXiv上发布了902篇GAN ...
- PAT甲级 1129. Recommendation System (25)
1129. Recommendation System (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...
- js-图片轮播
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- 编写高质量iOS与OS X代码的52个有效方法
第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...
- 2.启动MySql服务
windows10下启动mysql服务出现服务名无效的原因及解决方法 问题原因:mysql服务没有安装. 解决办法: 在 mysql bin目录下 以管理员的权限 执行 mysqld -install ...
- JS学习笔记7_表单脚本
1.获取表单及表单元素引用的方式 var mForm = document.forms[formName];获取表单引用 mForm.elements[elemName]获取表单元素,如有同名的,则得 ...
- 一步一步学习Swift之(三):巧用AutoLayout布局
一些初学者经常在使用autoLayout时,做得效果不太理想,经常会出现界面错乱的情况. 本文章用一个小实例说明autoLayout的使用 非常的简单,只要记住 规则就可以使界面适屏布局,适配各种ip ...
- Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...
- 【计算机网络】 DNS学习笔记 (>﹏<)
参考书籍 <计算机网络-自顶向下> 作者 James F. Kurose DNS的作用 DNS是因特网的目录服务 DNS是因特网的目录服务,它提供了主机名到IP地址映射的查询服务 ...
- 一起做OJ-环境搭建
这几天,看到OJ火了起来,尤其是OnlineJudge(QingDaoU)和HUSTOJ. 作为正在花大力研究PHP和Bootstrap的我,看到了,当然不会甘心. 于是,我决定把学到的知识用在编写O ...