lucene全文搜索之四:创建索引搜索器、6种文档搜索器实现以及搜索结果分析(结合IKAnalyzer分词器的搜索器)基于lucene5.5.3
前言:
前面几章已经很详细的讲解了如何创建索引器对索引进行增删查(没有更新操作)、如何管理索引目录以及如何使用分词器,上一章讲解了如何生成索引字段和创建索引文档,并把创建的索引文档保存到索引目录,到这里我们已经知道如何建立索引,那么本章将会详解如何搜索索引目录中的索引文档索以及如何创建索引搜索器和六种文档搜索器(搜索器)的实现。
luncene5.5.3集合jar包下载地址:http://download.csdn.net/detail/eguid_1/9677589
一、创建索引搜索器
索引搜索器由索引目录创建,依赖搜索器进行全文搜索,部分搜索器依赖分词器进行分词查询
1、创建索引目录搜索器(即索引搜索器)
根据索引目录创建索引搜索(如果有多个索引目录,那么需要创建多个索引搜索,分别搜索出结果后再对搜索结果进行合并调整)
/**
* 创建索引搜索
*
* @param indexReader -索引目录Reader
* @return
*/
public IndexSearcher createSearch(IndexReader indexReader) {
IndexSearcher indexSearch = null;
if (indexReader != null) {
indexSearch = new IndexSearcher(indexReader);
}
return indexSearch;
}
/**
* 创建索引搜索
* @param dir -索引目录
* @return
*/
public IndexSearcher createSearch(Directory dir) {
IndexSearcher indexSearch = null;
try {
IndexReader indexReader = DirectoryReader.open(dir);
indexSearch = new IndexSearcher(indexReader);
} catch (IOException e) { }
return indexSearch;
}
为了方便阅读,我们把六种搜索器放在最后, 这里先讲如何根据文档搜索器来搜索结果并且可以实现排序等等搜索结果的调整
2、搜索结果
/**
* 搜索
*
* @param search
* -索引搜索器
* @param query
* -查询器
* @param num
* -搜索结果数量
* @return
*/
public TopDocs search(IndexSearcher search, Query query, int num) {
TopDocs topDocs = null;
try {
topDocs = search.search(query, num);
} catch (IOException e) { }
return topDocs;
} /**
* 自定义排序搜索
*
* @param search
* -索引搜索
* @param query
* -查询器
* @param num
* -搜索结果数量
* @param sort
* -排序
* @return
*/
public TopDocs search(IndexSearcher search, Query query, int num, Sort sort) {
TopDocs topDocs = null;
try {
topDocs = search.search(query, num, sort);
} catch (IOException e) { }
return topDocs;
} /**
* 搜索
*
* @param search
* -索引搜索器
* @param query
* -查询器
* @param results
* -搜索结果
*/
public void search(IndexSearcher search, Query query, Collector results) {
try {
if (query != null && results != null)
search.search(query, results);
} catch (IOException e) { }
} /**
* 按照匹配分数搜索
*
* @param search
* @param query
* @param after
* -文档匹配分数
* @param numHits
* -命中数量
* @return
*/
public TopDocs search(IndexSearcher search, Query query, ScoreDoc after, int numHits) {
TopDocs topDocs = null;
try {
if (query != null && after != null)
topDocs = search.searchAfter(after, query, numHits);
} catch (IOException e) { }
return topDocs;
} /**
* 按照匹配分数搜索
*
* @param search
* @param query
* @param after
* -文档匹配分数
* @param numHits
* -命中数量
* @param sort
* 自定义排序
* @return 搜索结果
*/
public TopDocs search(IndexSearcher search, Query query, ScoreDoc after, int numHits, Sort sort) {
TopDocs topDocs = null;
try {
if (query != null && after != null && sort != null)
topDocs = search.searchAfter(after, query, numHits, sort);
} catch (IOException e) { }
return topDocs;
} /* 以下API已过时不建议再使用 */
public TopDocs search(IndexSearcher search, Query query, Filter filter, int results) {
TopDocs topDocs = null;
try {
topDocs = search.search(query, filter, results);
} catch (IOException e) { }
return topDocs;
} public TopDocs search(IndexSearcher search, Query query, Filter filter, int results, Sort sort) {
TopDocs topDocs = null;
try {
topDocs = search.search(query, filter, results, sort);
} catch (IOException e) { }
return topDocs;
} public TopDocs search(IndexSearcher search, Query query, Filter filter, int results, Sort sort, boolean doDocScores,
boolean doMaxScore) {
TopDocs topDocs = null;
try {
topDocs = search.search(query, filter, results, sort, doDocScores, doMaxScore);
} catch (IOException e) { }
return topDocs;
}
二、六种搜索器实现
/**
* 创建单词搜索器
*
* @param fieldName
* @param key
* @return
*/
public Query createTermQuery(String fieldName, String key) {
return new TermQuery(new Term(fieldName, key));
} /**
* 创建前缀搜索器
*
* @param fieldName
* @param key
* @return
*/
public Query createPrefixQeury(String fieldName, String key) {
return new PrefixQuery(new Term(fieldName, key));
} /**
* 创建范围搜索器
*
* @param fieldName
* @param start
* @param end
* @return
*/
public Query createNumericRangeQuery(String fieldName, int start, int end) {
return NumericRangeQuery.newIntRange(fieldName, start, end, true, true);
} /**
* 根据分词器创建条件搜索
*
* @param operator
* @param analyzer
* @param fieldName
* @param key
* @return
* @throws ParseException
*/
public Query createPhraseQueryByOperator(Operator operator, Analyzer analyzer, String fieldName, String key)
throws ParseException {
QueryParser qp = new QueryParser(fieldName, analyzer);
if (operator != null) {
qp.setDefaultOperator(operator);
}
return qp.parse(key);
} /**
* 根据分词器创建模糊搜索
*
* @param analyzer
* @param fieldName
* @param key
* @return
* @throws ParseException
*/
public Query createPhraseQuery(Analyzer analyzer, String fieldName, String key) throws ParseException {
return createPhraseQueryByOperator(null, analyzer, fieldName, key);
} /**
* 创建混合搜索器
*
* @return
*/
public BooleanQuery createBooleanQuery() {
return new BooleanQuery();
} /**
* 添加搜索器到混合搜索器
*
* @param booleanQuery
* @param occ
* @param query
*/
public void addToBooleanQuery(BooleanQuery booleanQuery, Occur occ, Query query) {
if (booleanQuery != null && query != null && occ != null) {
booleanQuery.add(query, occ);
}
}
三、搜索结果解析
public String[] parseQuery(TopDocs topDocs,IndexSearcher search,String fieldName){
int hits = 0;
if (topDocs != null && (hits = topDocs.totalHits) > 0)
{
ScoreDoc[] docs = topDocs.scoreDocs;
String[] results = new String[hits];
for (ScoreDoc doc : docs)
{
try {
//通过搜索结果找到对应文档
Document resultDoc = search.doc(doc.doc);
List<IndexableField> list=resultDoc.getFields();
for(IndexableField i:list)
{
System.out.println("名称:"+i.name()+",内容:"+i.stringValue()+",权重值:"+i.boost());
}
} catch (IOException e) {
}
}
return results;
}
return null;
}
四、测试搜索
Analyzer analyzer=createAnalyzer(false);
Directory dir=createDirectory(null, "d:","dir","search");
IndexWriterConfig conf=createIndexConf(analyzer, OpenMode.CREATE_OR_APPEND, false);
IndexWriter index=createIndex(dir, conf); //创建一个文档
Document doc=createDocument();
String[] states = new String[] {"欢迎来到eguid的博客", "欢迎大家来到eguid的技术博客", "欢迎大家来到eguid的技术博客,很开心能和大家一起分享开源技术"};
//创建字段
Field[] fields=createFields("字段名", states, TextField.TYPE_STORED, 1.1f);
//批量增加字段到索引文档
addFiledList(doc, fields);
//把索引文档保存到索引器
index.addDocument(doc);
close(index, true); //读取目录
IndexReader indexReader=DirectoryReader.open(dir);
//创建索引搜索器
IndexSearcher indexSearch=createSearch(indexReader);
try {
//创建文档搜索器
Query query=createPhraseQuery(analyzer, "字段名", "eguid");
//搜索结果
TopDocs topDocs=search(indexSearch, query, 2);
parseQuery(topDocs, indexSearch, "字段名");
//得到TopDocs,这个TopDocs就是一个结果文档,里面包含了搜索的结果内容,匹配度等等搜索计算结果参数
} catch (ParseException e) { }
搜索结果:
名称:字段名,内容:欢迎来到eguid的博客,权重值:1.0
名称:字段名,内容:欢迎大家来到eguid的技术博客,权重值:1.0
名称:字段名,内容:欢迎大家来到eguid的技术博客,很开心能和大家一起分享开源技术,权重值:1.0
到这里,lucene全文搜索的全部功能就全部实现了,而我们需要做的就是根据我们自己的业务对lucene的功能进行组合,从而实现我们的全文搜搜服务。
lucene全文搜索之四:创建索引搜索器、6种文档搜索器实现以及搜索结果分析(结合IKAnalyzer分词器的搜索器)基于lucene5.5.3的更多相关文章
- wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() { for { request : ...
- Elasticsearch 关键字:索引,类型,字段,索引状态,mapping,文档
1. 索引(_index)索引:说的就是数据库的名字.我这个说法是对应到咱经常使用的数据库. 结合es的插件 head 来看. 可以看到,我这个地方,就有这么几个索引,索引就是数据库,后面是这个数据库 ...
- CentOS6.4下使用默认的文档查看器打开PDF文档乱码的解决方案
最近在CentOS6.4下使用其默认的文档查看器打开PDF文档时出现乱码的方块,有两种方法可以解决. 方法一:修改/etc/fonts/conf.d/49-sansserif.conf文件,如 ...
- Lucene的配置及创建索引全文检索
Lucene 是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言).Lucene ...
- lucene正向索引(续)——一个文档的所有filed+value都在fdt文件中!!!
4.1.3. 域(Field)的数据信息(.fdt,.fdx) 域数据文件(fdt): 真正保存存储域(stored field)信息的是fdt文件 在一个段(segment)中总共有segment ...
- sphinx索引分析——文件格式和字典是double array trie 检索树,索引存储 – 多路归并排序,文档id压缩 – Variable Byte Coding
1 概述 这是基于开源的sphinx全文检索引擎的架构代码分析,本篇主要描述index索引服务的分析.当前分析的版本 sphinx-2.0.4 2 index 功能 3 文件表 4 索引文件结构 4. ...
- 使用dom解析器对xml文档内容进行增删查改
直接添代码: XML文档名称(one.xml) <?xml version="1.0" encoding="UTF-8" standalone=" ...
- Java DOM解析器 - 解析XML文档
使用DOM的步骤 以下是在使用DOM解析器解析文档使用的步骤. 导入XML相关的软件包. 创建DocumentBuilder 从文件或流创建一个文档 提取根元素 检查属性 检查子元素 导入XML相关的 ...
- Elasticsearch 索引、更新、删除文档
一.Elasticsearch 索引(新建)一个文档的命令: curl XPUT ' http://localhost:9200/test_es_order_index/test_es_order_t ...
随机推荐
- JS 部分常见循环、分支、嵌套练习
图形题思路:1.确定图形一共几行,即为外层的循环次数2.确定每行有几种元素,代表有几个内层循环3.确定每种元素的个数,即为每个内层循环的次数 通常,找出每种元素个数,与行号的关系式,即为当前内层循 ...
- 基于JS的问卷调查
主要工作 因为代码不好展示,也不好截长图,可以去看我的GitHub地址:https://github.com/14glwu/MyBlog/blob/master/questionnaire.html ...
- jQuery修炼心得-DOM节点的删除
要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题. 1.empty empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只移除了 指定元素中的所有子节点. ...
- android在myeclipse上创建的项目各种报错
这几天被android弄得头疼死了.差不多把电脑弄了个遍. 先是离线安装ADT,下载ADT,然后配置,但是因为ADT与MyEclipse冲突.所以直接不要再myeclipse下弄Android的环境了 ...
- PHP填补数字前后的0
PHP数字填补0 经常会遇到这样的问题: 自然数字是0,1,2,3...而我们需要的却是满足多少多少位数的数字,如:001,002. 在ID,编号,学号中我们会经常用到补全前面或者后面的空位(一般为前 ...
- Spring+SpringMvc+Mybatis 框架的搭建(一)
本文是因为实习结束后学习到了新的技术,想写下来和更多人交流.开发中遇到的问题我也会一一说明,希望有更多人可以互相探讨,加入到一起来. 1. Spring+SpringMvc +Mybatis 的作用有 ...
- laravel5 事务回滚
方法一 //不需要引入,直接开干 public function Transaction(){ DB::beginTransaction(); //开启事务 $sql1 = DB::table('de ...
- 写具有良好风格的ABAP代码
编程风格是一个经久不衰的话题,大家所公认的事实是:一个良好的编程风格会带来很多的好处.而对于“良好”的标准,则众说纷纭,莫衷一是.编程风格在ABAP程序中当然也有着重要的意义,因为很少看到专门针对AB ...
- java:Comparable比较器
/*Comparable 是java.lang中的一个接口,所以是默认导入的,不需要显示的导入. *如果你先直接在本类中实现排序,那么可以直接实现该接口(例如:public class Compara ...
- IOS的KVC
KVC作用 KVC类似于java中的反射,它是通过一个字符串 key 来获取和设置对应类中成员属性的值而key就是用来遍历某一个类,去查找类内部是否有与key同名的成员属性 所以对于KVC来说,成员属 ...