热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LuceneinAction为应用程序添加搜索功能

2019独角兽企业重金招聘Python工程师标准QueryParser类的使用matchVersion值的是版本(为了兼容)解析表达式不成功抛出P

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

a6dec7047f737aa031515cc7268a183dd3a.jpg

d2e3d0f3fdcead04a99a7dd27712f29efdc.jpg

ae8c6d9c7750fe5c85aff0cbb6197609544.jpg

QueryParser 类的使用

  • f009f60043851ab3f9c91797a2152f1d71f.jpg
    • matchVersion 值的是 版本(为了兼容)
  • a64d917db5730ab5c4552f667bcf2b9d418.jpg
    • 解析表达式
    • 不成功抛出 ParseException
    • 多个项时,默认是OR
    • 3279b25de68c34221431e00824e8a56b6a1.jpg
    • 7abea7873140703ea7fc6a6bd3354d10236.jpg

IndexSearcher

  • IndexReader 打开索引文件、提供底层redaer API 的繁重工作
    • 需要较大系统开销
    • 在搜索其间最好打开一个大家公用就好
    • 需要限制其打开的频率(可以类似 数据库 connection处理)
      • reopen 消耗较少的系统资源
      • 如果索引变更,会返回新的reader ,和旧的不一样 
        • 此时依然有很多程序在使用旧的reader ,请保证线程安全
        • 如下所示,如果不一样,想看到新的索引,需要创建新的IndexSearcher
      • 52c8093fda503c230ba682556461008b7ca.jpg
  • 9fb992e06020e4914fe8d0028cacddc898a.jpg

实现搜索功能

  • search() 方法
    • 其他高级搜索包括过滤和排序
    • 773f54412c0273f4f711663187b61bb3269.jpg

使用TopDocs 类

  • TopDocs.totalHits
  • TopDocs.scoreDocs:匹配的顶部文档数组
  • 14ca66458dc3ed32081f7eed5f3ba404430.jpg

搜索结果分页

  • 分页两种实现:
    • 17194b7d6e0ae213fe1d02fceb38f59b9ca.jpg
      • 重新查询往往更好,Lucene的高性能查询弥补了其浪费资源的短板
        • 操作系统的I/O缓存机制,使得重新查询很快结束

近实时搜索

  • 不必关闭writer、再向该writer 提交
  • 长期打开一个IndexWriter 完成持续变更
    • 允许对新创建的、还未提交的段进行搜索
  • public class NearRealTimeTest extends TestCase {public void testNearRealTime() throws Exception {Directory dir &#61; new RAMDirectory();IndexWriter writer &#61; new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED);for(int i&#61;0;i<10;i&#43;&#43;) {Document doc &#61; new Document();doc.add(new Field("id", ""&#43;i, Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));doc.add(new Field("text", "aaa", Field.Store.NO, Field.Index.ANALYZED));writer.addDocument(doc);}// 会将缓存中所有变更&#xff0c;刷新到索引目录&#xff0c;返回一个包含这些变更的新的readerIndexReader reader &#61; writer.getReader(); // #1 创建近实时 readerIndexSearcher searcher &#61; new IndexSearcher(reader); // #AQuery query &#61; new TermQuery(new Term("text", "aaa"));TopDocs docs &#61; searcher.search(query, 1);assertEquals(10, docs.totalHits); // #Bwriter.deleteDocuments(new Term("id", "7")); // #2Document doc &#61; new Document(); // #3doc.add(new Field("id", // #3"11", // #3Field.Store.NO, // #3Field.Index.NOT_ANALYZED_NO_NORMS)); // #3doc.add(new Field("text", // #3"bbb", // #3Field.Store.NO, // #3Field.Index.ANALYZED)); // #3writer.addDocument(doc); // #3// reopen 完成更多变更&#xff0c;效率很高&#xff1a;// 只会打开上次open、reopen的文件// 未发生任何改变的被共享&#xff08;共享先前的reader&#xff09; IndexReader newReader &#61; reader.reopen(); // #4assertFalse(reader &#61;&#61; newReader); // #5reader.close(); // #6searcher &#61; new IndexSearcher(newReader); TopDocs hits &#61; searcher.search(query, 10); // #7assertEquals(9, hits.totalHits); // #7query &#61; new TermQuery(new Term("text", "bbb")); // #8hits &#61; searcher.search(query, 1); // #8assertEquals(1, hits.totalHits); // #8newReader.close();writer.close();}
    }/*#1 Create near-real-time reader#A Wrap reader in IndexSearcher#B Search returns 10 hits#2 Delete 1 document#3 Add 1 document#4 Reopen reader#5 Confirm reader is new#6 Close old reader#7 Verify 9 hits now#8 Confirm new document matched
    */

理解Lucene的 评分机制

  • 评分公式(详见之前博客的推导公式)&#xff1a;
    • 835bfcd101036b335a387179383d491cde1.jpg
    • debfccc9decbcc6f778c0c35c78ce6e1446.jpg

explain() 方法理解搜索结果评分&#xff1a;

  • 开销和查询是一样的&#xff0c;不要过度使用
  • public class Explainer {public static void main(String[] args) throws Exception {if (args.length !&#61; 2) {System.err.println("Usage: Explainer ");System.exit(1);}String indexDir &#61; args[0];String queryExpression &#61; args[1];Directory directory &#61; FSDirectory.open(new File(indexDir));QueryParser parser &#61; new QueryParser(Version.LUCENE_30,"contents", new SimpleAnalyzer());Query query &#61; parser.parse(queryExpression);System.out.println("Query: " &#43; queryExpression);IndexSearcher searcher &#61; new IndexSearcher(directory);TopDocs topDocs &#61; searcher.search(query, 10);for (ScoreDoc match : topDocs.scoreDocs) {Explanation explanation&#61; searcher.explain(query, match.doc); //#ASystem.out.println("----------");Document doc &#61; searcher.doc(match.doc);System.out.println(doc.get("title"));System.out.println(explanation.toString()); //#B}searcher.close();directory.close();}
    }

     

Lucene 多样化查询&#xff1a;

  • 详见之前博客内容

解析查询表达式&#xff1a;QueryParser

  • 需要转义的字符&#xff1a;
    • f3903a23b4508b0df5249d1d546151d208c.jpg
  • Query.toString()
    • 查看 QueryParser 对象解析后的样子

TermQuery

  • 356a8d1ebf62a5253744c904b4b6fc53fa3.jpg
  • 174990554eb6a55c9e135680ca681c0f805.jpg
    • 将 查询自动解析为 输出的样子

项范围查询&#xff1a;

  • [] 边界值包含在内&#xff0c;{} 不包含在内
    • 49350fd6834b4effae652e960f647b9ba62.jpg

通配符查询仅仅在末尾有一个*

  • 会被优化为前缀查询
  • 二者都会转化大小写&#xff0c;不过能人为设置不转化
    • 286ce1d1dd0c79122cf42ae8a29ad3e4835.jpg

布尔查询&#xff1a;&#xff1a;

  • AND OR NOT 必须全部大写
  • 默认是OR &#xff08;a  b   默认认为是 a OR b&#xff09;
  • 可修改默认&#xff1a;
    • 53dea9a7de30e138c1fe381fa0123dc8b4c.jpg
  • NOT 不能单独使用
  • c2e4c3af63994e6bf86418f3b1f89f9e713.jpg

短语查询&#xff1a;

  • 双引号括起来的项&#xff0c;转化为短语查询
    • “this is tom cat*”  
      • 分析结果 tom  cat   
        • 注意 前俩是停用词
        • 最后的* 在双引号内不考虑
    • 3ecf870bfa66c987454317e8c9245484d11.jpg
      • 不设置slop 默认值为0
    • SpanNearQuery 确保按照顺序
    • PhraseQuery 松散的&#xff0c;不一定按照顺序

模糊查询&#xff1a;

  • f4fb58b0d539381fbdd6518789025867691.jpg
  • ~0.7 指定最小相似 程度

MatchAllDocsQuery

  • *&#xff1a;*   会被解析为 MatchAllDocsQuery

分组查询&#xff1a;

  • 小括号&#xff0c;来建立子查询
    • 75bb95e9e816904507c45daaac82a92b341.jpg
    • 306b5a111948f1f2a620e01760515012b54.jpg

域选择&#xff1a;

  • 要求用户知道被搜索的域是不太友善的
    • 默认的域在创建QueryParser 时创建
    • 也可以指定默认域为所有域
      • title&#xff1a;lucene 限定查询域为title
      • filed &#xff08;a b c&#xff09;
        • filed&#xff1a;a OR filed&#xff1a;b OR filed&#xff1a;c

为子查询加权

  • 598a3feb4bbf53ef6ed0b6ae13c23552164.jpg
  • junit 加权为 2.0   testing 1.0

是否一定使用QueryParser

  • QueryParser 提供了快捷强大的查询构建
    • 不能适合所有的场合

转:https://my.oschina.net/u/3847203/blog/2999334



推荐阅读
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
author-avatar
赤木律孑
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有