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 初探 - 查询的更多相关文章

  1. lucene 初探

    前言: window文件管理右上角, 有个搜索功能, 可以根据文件名进行搜索. 那如果从文件名上判断不出内容, 我岂不是要一个一个的打开文件, 查看文件的内容, 去判断是否是我要的文件? 几个, 十几 ...

  2. Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser

    一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...

  3. Hibernate Search集与lucene分词查询

    lucene分词查询参考信息:https://blog.csdn.net/dm_vincent/article/details/40707857

  4. Lucene的查询语法,JavaCC及QueryParser(1)

    http://www.cnblogs.com/forfuture1978/archive/2010/05/08/1730200.html 一.Lucene的查询语法 Lucene所支持的查询语法可见h ...

  5. Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser 2014-06-25 14:25 722人阅读 评论(1) 收藏

    一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...

  6. 全文检索Lucene框架---查询索引

    一. Lucene索引库查询 对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name ...

  7. 【手把手教你全文检索】Apache Lucene初探

    PS: 苦学一周全文检索,由原来的搜索小白,到初次涉猎,感觉每门技术都博大精深,其中精髓亦是不可一日而语.那小博猪就简单介绍一下这一周的学习历程,仅供各位程序猿们参考,这其中不涉及任何私密话题,因此也 ...

  8. [转载] Apache Lucene初探

    转载自http://www.cnblogs.com/xing901022/p/3933675.html 讲解之前,先来分享一些资料 首先呢,学习任何一门新的亦或是旧的开源技术,百度其中一二是最简单的办 ...

  9. 【手把手教你全文检索】Apache Lucene初探 (zhuan)

    http://www.cnblogs.com/xing901022/p/3933675.html *************************************************** ...

随机推荐

  1. 一个支持邮件带附件群发的java类

    import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.Date;import ...

  2. svn本地如何切换账号

    SVN如何切换账号   在使用svn更新或提交数据时需要输入用户名和密码,在输入框中可以选择是否记录,以便下次操作无需再次输入用户名和密码: 要切换其他用户名时,需要删除已记录用户的数据,在电脑桌面上 ...

  3. java基本数据类型与封装类型详解(int和Integer区别)

    int是java提供的8种原始数据类型之一. Java为每个原始类型提供了封装类,Integer是java为int提供的封装类(即Integer是一个java对象,而int只是一个基本数据类型).in ...

  4. codeforce864d

    D. Make a Permutation! time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  5. 图解FTP服务器搭建(Windows Server 2008)

    http://wenku.baidu.com/link?url=aUMoUYvSXKbHdbOHt4lUUCq0BhjnPRTM8jNb80jjwJ4_CM5LFq3lSm6f1ZlPNbFo6HEj ...

  6. 3.Ubuntu下安装mysql并在windows下使用Navicat来连接

    一.安装mysql(只需要三条命令) 1.第一条命令(中间需要输入root用户密码): sudo apt-get install mysql-server 2.第二条命令: sudo apt-get ...

  7. C# 利用VS中的插件来打包并发布winfrom程序

    1.先在VS 的扩展更新中搜索此插件[2015 installer Projects],点击下载,安装需要关闭VS 2.安装完毕之后新建项目 3.选择“application folder”项,然后在 ...

  8. [实战演练]蜻蜓FM2014年校招笔试题目 - 规则二叉树

    题目:某规则二叉树的定义是:对于树中任意两个叶结点A.B,他们与根结点的距离分别是d1和d2,|d1-d2|<=1.请写出函数 bool isRuledTree(Node *root)的代码实现 ...

  9. 「PKUWC2019」拓扑序计数(状压dp)

    考场只打了 \(52\) 分暴力...\(ljc\) 跟我说了一下大致思路,我回去敲了敲. \(f[i]\) 表示状态为 \(i\) 时的方案数.我们用二进制 \(0/1\) 表示不选/选点 \(i\ ...

  10. PHP程序员职业发展路线

    重点:把LNMP搞熟练(核心是安装配置基本操作) 1.Linux: 基本命令.操作.启动.基本服务配置(包括rpm安装文件,各种服务配置等): 会写简单的shell脚本和awk/sed 脚本命令等. ...