Lucene之模糊、精确、匹配、范围、多条件查询
Lucene的查询方式很 丰富,对于数值类型的数据,采取TermRangeQuery的方式,对于String类型的,就可以采取TermQuery等,查询方式了,可以通过采取合适的查询方式,检索到数据。Queryparser这个查询方式包含了其他几种查询方式。
查询方式
查询方式 | 意义 |
---|---|
TermQuery | 精确查询 |
TermRangeQuery | 查询一个范围 |
PrefixQuery | 前缀匹配查询 |
WildcardQuery | 通配符查询 |
BooleanQuery | 多条件查询 |
PhraseQuery | 短语查询 |
FuzzyQuery | 模糊查询 |
Queryparser | 万能查询(上面的都可以用这个来查询到) |
案例
package com.yellowcong.demo; import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version; /**
* 创建用户:狂飙的yellowcong<br/>
* 创建时间:下午5:27:50<br/>
* 创建日期:2017年12月2日<br/>
* 机能概要:
*/
public class Demo4 {
private static List<Passage> psgList = null; // 写对象
private static IndexWriter writer = null; public static void main(String[] args) throws Exception { // 删除 所有索引
deleteAll(); // 建立索引
index(); //精确String 类型查询
getByTermQuery(); //范围查询
getByRange(); //前缀匹配查询
getByPrefix(); //通配符查询
getByWildcard(); //短语查询
getByPhrase(); //模糊查询
getByFuzzy();
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:00:43<br/>
* 机能概要:精确查询
* @throws Exception
*/
public static void getByTermQuery() {
System.out.println("-------------查询用户名为yellowcong的数据-------------");
//精确查询,根据名称来直接
Query query = new TermQuery(new Term("username", "yellowcong")); //执行查询
excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:25:21<br/>
* 机能概要:范围查询
*/
public static void getByRange(){
//精确查询
System.out.println("-------------查询id在1-3的数据-------------");
//查询前三条数据,后面两个true,表示的是是否包含头和尾
Query query = NumericRangeQuery.newIntRange("id", 1, 3, true, true);
//执行查询
excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:25:56<br/>
* 机能概要:前缀查询数据
*/
public static void getByPrefix(){
System.out.println("-------------查询前缀 邮箱 以z开头的数据-------------");
//查询前缀 邮箱 以z开头的数据
Query query = new PrefixQuery(new Term("email", "z")); //执行查询
excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:29:55<br/>
* 机能概要:通配符查询数据
*/
public static void getByWildcard(){
//通配符就更简单了,只要知道“*”表示0到多个字符,而使用“?”表示一个字符就行了
System.out.println("-------------------查询email 以 @qq结尾的数据--------------");
//查询email 以 @qq结尾的数据
Query query = new WildcardQuery(new Term("email","*@qq.com"));
//执行查询
excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:43:43<br/>
* 机能概要:短语查询,查询中间有几个单词的那种
*/
public static void getByPhrase(){
System.out.println("------------查询内容中,有I LOVE YOU 的数据---------------");
//短语查询,但是对于中文没有太多的用,其中查询的时候还有
PhraseQuery query = new PhraseQuery();
//设定有几跳,表示中间存在一个单词
query.setSlop(1);
//查询
query.add(new Term("content","i")); //I XX you 就可以被查询出来
query.add(new Term("content","you")); excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:49:14<br/>
* 机能概要:默认提供的模糊查询对中文来说,没有任何用
* @throws Exception
*/
public static void getByFuzzy() throws Exception{
System.out.println("-------------------------模糊查询---------------");
FuzzyQuery query = new FuzzyQuery(new Term("username","zhangsan"));
excQuery(query);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:下午12:01:55<br/>
* 机能概要:查询Query 将需要查询的条件传递进来
* @param query
*/
public static void excQuery(Query query){
//查询
IndexReader reader = null;
try {
reader = getIndexReader(); //获取查询数据
IndexSearcher searcher = new IndexSearcher(reader); //检索数据
TopDocs topDocs = searcher.search(query, 100);
for(ScoreDoc scoreDoc : topDocs.scoreDocs){
//湖区偶
Document doc = reader.document(scoreDoc.doc);
System.out.println(doc.get("id")+":"+doc.get("username")+":"+doc.get("email"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
coloseReader(reader);
}
}
/**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月3日<br/>
* 创建时间:上午11:52:52<br/>
* 机能概要:关闭IndexReader
* @param reader
*/
private static void coloseReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} static {
psgList = new ArrayList<Passage>(); // 产生一堆数据
psgList.add(new Passage(1, "yellowcong" ,
"717350389@qq.com", "逗比", 23 , "I LOVE YOU ", new Date())); psgList.add(new Passage(2, "张三" ,
"zhashang@qq.com", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(3, "李四" ,
"lisi@neusoft.com", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(4, "王五" ,
"wangwu@aliyun.com", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(5, "赵六" ,
"zhaoliu@baidu.com", "逗比", 23, "三炮", new Date()));
System.out.println("-------------------------添加的数据----------------------");
for(Passage psg:psgList){
System.out.println(psg.getId()+":"+psg.getUsername()+":"+psg.getEmail()+":"+psg.getContent());
}
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午5:43:57<br/>
* 机能概要:获取IndexWriter 同一时间 ,只能打开一个 IndexWriter,独占写锁 。内建线程安全机制。
*
* @return
* @throws Exception
*/
@SuppressWarnings("static-access")
public static IndexWriter getIndexWriter() throws Exception {
// 创建IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 判断资源是否占用
if (writer == null || !writer.isLocked(fs)) {
synchronized (Demo3.class) {
if (writer == null || !writer.isLocked(fs)) {
// 创建writer对象
writer = new IndexWriter(fs,
new IndexWriterConfig(Version.LUCENE_45, new StandardAnalyzer(Version.LUCENE_45)));
}
}
}
return writer;
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午5:46:36<br/>
* 机能概要:获取到IndexReader 任意多个IndexReaders可同时打开,可以跨JVM。
*
* @return
* @throws Exception
*/
public static IndexReader getIndexReader() throws Exception {
// 创建IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 获取到读
return IndexReader.open(fs);
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午7:57:04<br/>
* 机能概要:删除所有的索引
*/
public static void deleteAll() {
IndexWriter writer = null;
try {
// 获取IndexWriter
writer = getIndexWriter(); // 删除所有的数据
writer.deleteAll(); int cnt = writer.numDocs();
System.out.println("索引条数\t" + cnt); // 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午5:37:22<br/>
* 机能概要:获取索引目录
*
* @return 目录
*/
private static String getIndexPath() {
// 获取索引的目录
String path = Demo3.class.getClassLoader().getResource("index").getPath(); // 不存在就创建目录
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path;
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午8:24:16<br/>
* 机能概要:关闭IndexWriter
*/
private static void coloseWriter(IndexWriter writer) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午8:26:15<br/>
* 机能概要:关闭IndexReader
*
* @param reader
*/
public static void closerReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午8:10:01<br/>
* 机能概要: 查询数据
*
* @param key
* 查询范围
* @param val
* 值
*/
public static void search(String key, Object val) {
IndexReader reader = null;
try {
reader = getIndexReader(); IndexSearcher searcher = new IndexSearcher(reader); // 精确查询
Query query = null; // 定义查询条件
if (val instanceof Integer) {
// 后面的两个true 表示的是 是否包含 上下的数据
query = NumericRangeQuery.newIntRange(key, Integer.parseInt(val.toString()),
Integer.parseInt(val.toString()), true, true);
} else {
query = new TermQuery(new Term(key, val.toString()));
}
// QueryParser paraser = new QueryParser(Version.LUCENE_45, key, new
// StandardAnalyzer(Version.LUCENE_45));
// Query query = paraser.parse(val); // 获取查询到的Docuemnt
TopDocs topDocs = searcher.search(query, 500);
// 总共命中的条数
System.out.println(topDocs.totalHits);
for (ScoreDoc score : topDocs.scoreDocs) {
//
Document doc = searcher.doc(score.doc); // 查询到的结果
String username = doc.get("username");
System.out.println(username);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closerReader(reader);
}
} /**
* 创建用户:狂飙的yellowcong<br/>
* 创建日期:2017年12月2日<br/>
* 创建时间:下午6:03:33<br/>
* 机能概要:建立索引
*/
public static void index() {
IndexWriter writer = null;
try {
// 1、获取IndexWriter
writer = getIndexWriter(); // 2、建立索引
for (Passage psg : psgList) {
Document doc = new Document(); // IntField 不能直接检索到,需要结合
doc.add(new IntField("id", psg.getId(), Field.Store.YES)); // 用户String类型的字段的存储,StringField是只索引不分词
doc.add(new TextField("username", psg.getUsername(), Field.Store.YES)); // 主要对int类型的字段进行存储,需要注意的是如果需要对InfField进行排序使用SortField.Type.INT来比较,如果进范围查询或过滤,需要采用NumericRangeQuery.newIntRange()
doc.add(new IntField("age", psg.getAge(), Field.Store.YES)); // 对String类型的字段进行存储,TextField和StringField的不同是TextField既索引又分词
doc.add(new TextField("content", psg.getContent(), Field.Store.NO)); doc.add(new StringField("keyword", psg.getKeyword(), Field.Store.YES)); doc.add(new StringField("email", psg.getEmail(), Field.Store.YES)); // 日期数据添加索引
doc.add(new LongField("addDate", psg.getAddDate().getTime(), Field.Store.YES)); // 3、添加文档
writer.addDocument(doc);
} // 索引条数
int cnt = writer.numDocs();
System.out.println("索引条数\t" + cnt); // 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
} static class Passage {
private int id;
private String username;
private String email;
private String keyword;
private int age;
// 这个模拟的是文章
private String content;
private Date addDate; public Passage(int id, String username, String email, String keyword, int age, String content, Date addDate) {
super();
this.id = id;
this.username = username;
this.email = email;
this.keyword = keyword;
this.age = age;
this.content = content;
this.addDate = addDate;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getKeyword() {
return keyword;
} public void setKeyword(String keyword) {
this.keyword = keyword;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public Date getAddDate() {
return addDate;
} public void setAddDate(Date addDate) {
this.addDate = addDate;
}
}
}
Lucene之模糊、精确、匹配、范围、多条件查询的更多相关文章
- Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析
缘由 数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询. 技术方案 考虑 ...
- grep精确匹配搜索某个单词的用法 (附: grep高效用法小结))
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正 ...
- 通过带参数的Sql语句来实现模糊查询(多条件查询)
#region 通过带参数的Sql语句来实现模糊查询(多条件查询) StringBuilder sb = new StringBuilder("select * from books&quo ...
- 三思考,实现自己定义404页:Tomcat、SpringMVC精确匹配、重写DispatchServlet
第1种方式:Tomcat直接处理 web.xml <error-page> <error-code>404</error-code> <location> ...
- awk使用正则精确匹配
[root@localhost home]# cat file 5001][YRSD5-1][YRSD5-1-2][0203008400028411] 010102 5001][YRSD7-1][YR ...
- 使用 grep 的 -o 和 -E 选项进行正则的精确匹配
sed 命令可以很好的进行行匹配,但从某一行中精确匹配某些内容,则使用 grep 命令并辅以 -o 和 -E 选项可达到此目的.其中 -o 表示“only-matching”,即“仅匹配”之意.光用它 ...
- Solr的精确匹配搜索
情景: 利用Solr做一批词的逆文档频率.Solr中存储的每条数据为一篇文章,此时需要查出某词在多少篇文章中出现过,然后用公式:某词逆文档频率 = 总文章数 / (出现过某词的文章数+1) 来计算. ...
- vim 精确匹配查找单词【转】
删除文件中所有的空行:g/^\s*$/d 去掉所有的行尾空格::%s/\s\+$// 整个文件特定字符串的替换:%s/old_word/new_word/g 删除从当前行开始到最后一行的所有内容:., ...
- lucene多条件查询”搜索—BooleanQuery
/** * “多条件查询”搜索—BooleanQuery * BooleanQuery也是实际开发过程中经常使用的一种Query. * 它其实是一个组合的Query,在使用时可以把各种Query对象添 ...
随机推荐
- Android开源项目汇总
Android很多优秀的开源项目,很多UI组件以及经典的HTTP 访问开源,都能给我们带来一些自己项目的启迪或者引用. 下面简单介绍一下自己收藏的一些项目内容. 项目: Apollo音乐播放器:And ...
- zufeoj 1018 阶乘第k位是多少(sprintf)
题目描述 n的阶乘定义为n!=1*2*3*……*n 如3!=6 n!通常最后会有很多0,如5!=120 最后有一个0,现在统计n!去除末尾的0后,最后k位是多少 输入 第一 ...
- [转]C# int.ToString()
原文链接:https://msdn.microsoft.com/zh-cn/library/dwhawy9k 原文链接:https://msdn.microsoft.com/zh-cn/library ...
- ESN
1.对于一般的硬件设备,ESN是设备序列号,主要用来识别设备,包括未来服务鉴权的需要 2.对于需要license的设备,ESN也是设备序列号的意思,只不过这个序列号可能是根据设备硬件信息算出来的一串字 ...
- 北京师范大学第十六届程序设计竞赛决赛-重现赛-B题
一.题目链接 https://www.nowcoder.com/acm/contest/117/B 二.题意 给定一组序列$a_1,a_2,\cdots,a_n$,表示初始序列$b_1,b_2,\cd ...
- Python unittest excel数据驱动
安装xlrd 下载地址:https://pypi.python.org/pypi/xlrd 安装ddt 下载地址:https://pypi.python.org/pypi/ddt/1.1.0 clas ...
- MySQL GTID (四)
七. GTID的限制以及解决方案 7.1 事务中混合多个存储引擎,会产生多个GTID. 当使用GTID,在同一个事务中,更新包括了非事务引擎(MyISAM)和事务引擎(InnoDB)表的操作,就会导致 ...
- java 重定向和转发 的区别
重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求.因为,当你使用重定向时,浏览器中所显示的URL会变成新页面的URL, 而当使用转发时,该URL会保持不变. 重定向的速度比转发慢,因为浏览器 ...
- pg_hba.conf、pool_hba.conf 以及 pool_passwd 三者间的关系
pg_hba.conf.pool_hba.conf 以及 pool_passwd 三者间的关系: 1.pg_hba.conf.pool_hba.conf 以及 pool_passwd 三者关系 pg_ ...
- C++实现:把一个文件夹里的冗余文件(.txt)删除
代码很简单,调用了MFC里的几个函数.这里的冗余判断,是要遍历文件内容,进行两两比较. 需要注意的地方有两点: 1.源文件里头文件<afx.h>必须放在最前面.这里是为了避免nafxcwd ...