2019独角兽企业重金招聘Python工程师标准>>>

查询这个功能很强大,也可以说是lucene搜索最重要的功能之一,但是这个功能对英文也来比较好用,对中文支持来说,就不那么理想了。

查询支持种类很多,最简单的是TermQuery,其次是TermRangeQuery、PrefixQuery、BooleanQuery、PhraseQuery等等,看起来确实很丰富,特别是PhraseQuery这种查询,就是通过短语来进行查询,听起来很不错,可惜经过本人尝试和网上了解,这个对中文根本行不通。退而求其次,BooleanQuery相对来说靠谱一点,但稍微要注意一些东西。

BooleanQuery用途大概是这样,比如有句话为

感恩南无大慈大悲救苦救难广大灵感观世音菩萨摩诃萨

我们输入两个关键字“南无“、”观世音“,如果采用 BooleanQuery查询,可以使用类似于"and"、“or"这样的逻辑关系来组合查询,只是BooleanQuery里面的对应的是:

BooleanClause.Occur.MUST(必须包括此关键字)
BooleanClause.Occur.MUST_NOT(必须不包括此关键字)
BooleanClause.Occur.SHOULD(可以包含)

下面我们来看一个实际的例子:

public static void main(String[] args) throws Exception {Directory dir = new RAMDirectory();Analyzer analyzer = new MyIKAnalyzer();IndexWriterConfig config = new IndexWriterConfig(analyzer);IndexWriter writer = new IndexWriter(dir,config);writer.addDocument(getDoc("感恩南无大慈大悲救苦救难广大灵感观世音菩萨摩诃萨"));writer.addDocument(getDoc("观世音菩萨摩诃萨"));writer.close();IndexReader reader = DirectoryReader.open(dir);IndexSearcher searcher = new IndexSearcher(reader);BooleanQuery.Builder builder = new BooleanQuery.Builder();QueryParser queryParser = new QueryParser("field",analyzer);builder.add(queryParser.parse("观世音菩萨"), BooleanClause.Occur.MUST);builder.add(queryParser.parse("感恩"), BooleanClause.Occur.MUST);TopScoreDocCollector collector = TopScoreDocCollector.create(10);searcher.search(builder.build(), collector);ScoreDoc[] hits = collector.topDocs().scoreDocs;System.out.println("Found " + hits.length + " hits.");for(int i=0;i<hits.length;++i) {int docId = hits[i].doc;Document d = searcher.doc(docId);System.out.println((i + 1) + ". " + d.get("field") );}reader.close();}private static Document getDoc(String field) throws IOException {Document doc = new Document();doc.add(new TextField("field", field, Field.Store.YES));return doc;}

上面的代码不做多说,只说一个地方,BooleanQuery这个在6.0版本里面不能直接用new BooleanQuery()这种形式构造,而是通过new BooleanQuery.Builder()创建一个BooleanQuery.Builder对象,而且Builder对象add的对象不能是TermQuery这种对象,而是要由QueryParser解析后对象,如上面代码中的:

builder.add(queryParser.parse("观世音菩萨"),。。。。。);

不然的话,中文词组就查不出来,这点至关重要。 最后获取BooleanQuery查询对象是这么获取的:

builder.build()

记住,获取查询对象必须要放在添加组合查询之后。

下面来一个highlighter与booleanQuery查询相结合的例子吧,直接上代码:

public static void main(String[] args) throws Exception {String text = readFile("d:/content1.txt");//设置高亮文本的样式Formatter formatter = new SimpleHTMLFormatter("<span>", "</span>");//通过TokenStream流获取存储分词的各种信息Analyzer analyzer = new MyIKAnalyzer();Query query = getBooleanQuery(analyzer);TokenStream tokenStream = analyzer.tokenStream("field",new StringReader(text));//通过评分后的查询对象QueryScorer scorer = new QueryScorer(query,"field");Highlighter highlighter = new Highlighter(formatter,scorer);
//        默认情况下,highlighter内部使用的是SimpleFragmenter分成片断,如果满足不了需求,可以用SimpleSpanFragmenterhighlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer));System.out.println(highlighter.getBestFragment(tokenStream,text));}static String readFile(String filename) throws Exception {String line = null;StringBuilder records = new StringBuilder();BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));while ((line = bufferedReader.readLine()) != null) {records.append(line);}bufferedReader.close();return records.toString();}public static Query getBooleanQuery(Analyzer analyzer) throws ParseException {BooleanQuery.Builder builder = new BooleanQuery.Builder();QueryParser queryParser = new QueryParser("field",analyzer);builder.add(queryParser.parse("地藏菩萨"), BooleanClause.Occur.MUST);builder.add(queryParser.parse("南无"), BooleanClause.Occur.MUST);return builder.build();}

注意,我已经在ext.dic里面添加了“地藏菩萨”这个词组,上面的程序运行结果如下:

早晨请这个水喝,在二十四小时之内,心里思念<span>地藏菩萨</span>名号“<span>南无</span><span>地藏菩萨</span>”六字,喝的时候长跪捧这杯水,要发愿请<span>地藏菩萨</span>加持。这部经上指示说面向南,南西北方都是不定的,你的意念对着<span>地藏菩萨</span>像就行了,想的是南方

需要注意的是,获取BooleanQuery查询对象的位置要放在获取tokenStream之前,不然会报错。从上面运行输出来看,结果相当完美。

转载于:https://my.oschina.net/moluyingxing/blog/673024

Highlighter与BooleanQuery查询相关推荐

  1. Spring Boot操作ES进行各种高级查询(值得收藏)

    作者 | 后青春期的Keats 来源 | http://cnblogs.com/keatsCoder/p/11341835.html SpringBoot整合ES 创建SpringBoot项目,导入 ...

  2. elasticsearch(es)高级查询api

    yml配置 #es配置 spring:elasticsearch:rest:uris: 192.168.16.188:9200 添加依赖 <dependency><groupId&g ...

  3. SpringBoot操作ES进行各种高级查询(值得收藏)

    来源:cnblogs.com/keatsCoder/p/11341835.html SpringBoot整合ES 创建SpringBoot项目,导入 ES 6.2.1 的 RestClient 依赖和 ...

  4. SpringBoot 操作 ES 进行各种高级查询

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

  5. SpringBoot操作ES进行各种高级查询

    SpringBoot整合ES 创建SpringBoot项目,导入 ES 6.2.1 的 RestClient 依赖和 ES 依赖.在项目中直接引用 es-starter 的话会报容器初始化异常错误,导 ...

  6. java操作es之各种高级查询

    目录 一.springboot整合es 1.1 pom依赖 1.2 yml配置 1.3 创建索引 1.4 创建映射 1.5 写入数据 二.Java API操作ES 2.1 查询全部 2.2 精准匹配 ...

  7. ElasticSearch使用(嵌套查询、嵌套高亮)

    ElasticSearch使用(嵌套查询.嵌套高亮) 嵌套查询 bool 查询 must.should关系 1.只有must 2.只有should 3.must和should同时存在 4.怎样设置sh ...

  8. ElasticSearch安装、IK、映射、索引管理、搜索管理和集群管理

    ElasticSearch 一.ElasticSearch 1.1 概念 1.2 原理与应用 1.2.1 索引结构 1.2.3 RESTful应用 二.ElasticSearch安装 2.1 Wind ...

  9. 全文检索服务ElasticSearch

    1.ElasticSearch 介绍 1.1.为什么要用ElasticSearch? ​ 当我们访问购物网站的时候,我们可以根据我们随意所想的内容输入关键字就可以查询出相关的内容,这是怎么做到呢?这些 ...

最新文章

  1. 一只蝙蝠的自述,在朋友圈火了
  2. “比特币耶稣”Roger Ver:比特币现金分叉没有技术论据支持
  3. Minimum Depth of Binary Tree
  4. linux下shell编程
  5. nginx tomcat 负载
  6. struct和byte[]相互转换(用Marshal类实现)
  7. 推荐系统(1)-概述
  8. jdk的ServiceLoader
  9. 加载执行预编译的Sql :prepareStatement
  10. mysql数据签名功能_分析型数据库 MySQL的签名机制有哪些? -问答-阿里云开发者社区-阿里云...
  11. 如何设置、恢复默认浏览器为IE
  12. 中国鲷鱼养殖产量和捕捞产分析,养殖产业区域集中度高「图」
  13. Jspx.net Framework 6.38发布
  14. 《炬丰科技-半导体工艺》用于高效显示和通信的无磷白光 LED
  15. 英语笔记(计算机词汇,翻译/写作)
  16. 如何识破钓鱼邮件攻击
  17. 数学--数论--直角三角形--勾股数---奇偶数列法则 a^2+b^2=c^2
  18. oracle用plsql导出dmp文件
  19. Windows 10 IDM 下载play.kth.se上面的网课视频
  20. ASP.Net免费发送短信

热门文章

  1. 在微服务中,Kubernetes软件组件有哪些?
  2. 成为数据分析师需要具备的知识体系
  3. Kubernetes使用Nginx Ingress暴露Dashboard
  4. MATLAB R2018a 安装教程
  5. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(二)
  6. EF框架step by step(1)—Database-First
  7. 设计学习---《大象》之系统分析
  8. 关于VM虚拟机与主机不能互PING的一种可能的原因
  9. PHP类中Static方法效率测试
  10. 【重点 递归构造二叉树】LeetCode 95. Unique Binary Search Trees II