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之模糊、精确、匹配、范围、多条件查询的更多相关文章

  1. Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析

    缘由 数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询. 技术方案 考虑 ...

  2. grep精确匹配搜索某个单词的用法 (附: grep高效用法小结))

    grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正 ...

  3. 通过带参数的Sql语句来实现模糊查询(多条件查询)

    #region 通过带参数的Sql语句来实现模糊查询(多条件查询) StringBuilder sb = new StringBuilder("select * from books&quo ...

  4. 三思考,实现自己定义404页:Tomcat、SpringMVC精确匹配、重写DispatchServlet

    第1种方式:Tomcat直接处理 web.xml <error-page> <error-code>404</error-code> <location> ...

  5. awk使用正则精确匹配

    [root@localhost home]# cat file 5001][YRSD5-1][YRSD5-1-2][0203008400028411] 010102 5001][YRSD7-1][YR ...

  6. 使用 grep 的 -o 和 -E 选项进行正则的精确匹配

    sed 命令可以很好的进行行匹配,但从某一行中精确匹配某些内容,则使用 grep 命令并辅以 -o 和 -E 选项可达到此目的.其中 -o 表示“only-matching”,即“仅匹配”之意.光用它 ...

  7. Solr的精确匹配搜索

    情景: 利用Solr做一批词的逆文档频率.Solr中存储的每条数据为一篇文章,此时需要查出某词在多少篇文章中出现过,然后用公式:某词逆文档频率 = 总文章数 / (出现过某词的文章数+1) 来计算. ...

  8. vim 精确匹配查找单词【转】

    删除文件中所有的空行:g/^\s*$/d 去掉所有的行尾空格::%s/\s\+$// 整个文件特定字符串的替换:%s/old_word/new_word/g 删除从当前行开始到最后一行的所有内容:., ...

  9. lucene多条件查询”搜索—BooleanQuery

    /** * “多条件查询”搜索—BooleanQuery * BooleanQuery也是实际开发过程中经常使用的一种Query. * 它其实是一个组合的Query,在使用时可以把各种Query对象添 ...

随机推荐

  1. 使用libssh2连接到远程服务器

    libssh2-1.7.0.tar.gz  示例代码:libssh2-1.7.0.tar.gz\libssh2-1.7.0\example 官网示例 https://www.libssh2.org/e ...

  2. 使用protocol buffer时关闭警告

    在生成的文件头尾添加屏蔽警告的代码. 头部: #pragma warning(push, 2) // --------------------------------------------- 尾部: ...

  3. jQuery的文档操作

    1.插入操作 一.父元素.append(子元素) 追加某元素 父元素中添加新的元素 var oli = document.createElement('li'); oli.innerHTML = '哈 ...

  4. thinkphp5中Indirect modification of overloaded element of XXX has no effect的解决办法

    最近在使用Thinkphp5做foreach循环嵌套的时候报错:Indirect modification of overloaded element of XXX has no effect,网上搜 ...

  5. Advanced Simulation Library(ASL)&& An adaptive and distributed-memory parallel implementation of the immersed boundary (IB) method (IBAMR)

    How to install asl and ibamr tools: ASL 和 IBAMR 都是有限元分析的工具,流体力学等,ASL可以使用GPU加速计算, 主机配置,i7 6代,1060, 32 ...

  6. MVC中@Html.Action的用法

    MVC项目中如果有公共部分的代码就可以单独拿出来作为控件来用(比如头部和底部代码).跟ASP.NET中的ASCX实现的效果一样,但MVC比它方便的多. 想要实现该效果,需要知道@Html.Action ...

  7. 当前触发事件的两种方式(onclick) 和 ('id') 获取

    1. <input type='text' onclick = 'Clickon(this)'> <script> function Clickon(num){ num.sty ...

  8. centos7 ping www.baidu.com ping 不通。

    centos7 ping www.baidu.com ping 不通. 记录下,在搭建NodeJS服务器遇到的坑:centos7 ping www.baidu.com ping 不通. 1. 配置网卡 ...

  9. 迷你MVVM框架 avalonjs 0.96发布

    本版本主要是性能优化与 fix BUG,改进如下: 处理notifySubscribers中的BUG,它在标准浏览器不会移除那些无用的视图刷新函数.详见这里 重构modelBindling.SELEC ...

  10. 单词缩写集 · word abbreviation set

    [抄题]: 一个单词的缩写根据以下的形式.下面是一些缩写的例子 a) it --> it (没有缩写) 1 b) d|o|g --> d1g 1 1 1 1---5----0----5-- ...