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. bzoj4331: JSOI2012 越狱老虎桥

    Description 这里,是美丽的南京:这里,是秀美的进香河:这里是安逸的老虎桥.  如果说进香河的美,美在其秀美的风光,倒不如说是美在了那惬意的南京古典小巷式生活.如果说进香河的迷人,在其淳朴的 ...

  2. Linux C 一些函数 所属的头文件

    在编写程序时,有时总是不记得所使用的函数在哪个库函数中.现在先把自己以前经常用到的函数头文件总结一下. 有不对的地方还请指教. 1,系统调用文件的操作函数 #inlclude <fcntl.h& ...

  3. HyberLedger Fabric学习(3)-chaincode学习(开发者)

    参考:http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html chaincode是由go语言写的,实现了定义的接口. ...

  4. ASP.NET AJAX web chat application

    ASP.NET AJAX web chat application The project illustrates how to design a simple AJAX web chat appli ...

  5. Spring启动时获取自定义注解的属性值

    1.自定义注解 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documen ...

  6. Linux Tomcat 7.0 管理员登录时"401 Unauthorized" 问题解决方法

    http://blog.csdn.net/u010359532/article/details/36055291 tomcat 7.0没有默认值,需要在conf的tomcat-users.xml中设置 ...

  7. Shiro框架的简单应用

    一.概念 Shiro是一个安全框架,可以进行角色.权限管理. Shiro主要功能如下:Authentication(认证):用户身份识别,通常被称为用户“登录”Authorization(授权):访问 ...

  8. ios Https问题

    HTTPS认证过程:   ① 浏览器发送一个连接请求给安全服务器.   ② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器.   ③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的 CA ...

  9. Add Strings大整数加法十进制求和 & Add Binary二进制求和

    [抄题]: 以字符串的形式给出两个非负整数 num1 和 num2,返回 num1和 num2 的和. 比如一个50位+一个100位. 给定 num1 = "123",num2 = ...

  10. 用Diff和Patch工具维护源码

    在Unix系统下,维护源码版本可以使用很多方法,其中最常用的当然是大名鼎鼎的CVS,但实际上,简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具,Unix标配中的diff和patch工具 ...