当前位置 : 主页 > 网络推广 > seo >

Lucene-基础篇

来源:互联网 收集:自由互联 发布时间:2021-06-16
Lucene Lucene 介绍 它是一个构建搜索引擎核心类库,solr搜索引擎就是基于它去构建的,主要用来创建索引,查询索引(多中方式去查询) Lucene 搜索过程 (有点乱) 核心功能 创建索引 查询索

Lucene

Lucene 介绍

  • 它是一个构建搜索引擎核心类库,solr搜索引擎就是基于它去构建的,主要用来创建索引,查询索引(多中方式去查询)

Lucene 搜索过程 (有点乱)

  • 核心功能 创建索引 查询索引,基于海量数据的查询
  • 倒排索引
    • 比如100M的文本数据,将多文本逐行去查询,先进行分词,然后在提取关键词,建立索引库文件,根据用户输入的关键词去索引库去查询比对

Lucene 的依赖包

<dependencies>
   <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>4.10.2</version>
    </dependency>
    <!-- 查询索引的一些包 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queries</artifactId>
        <version>4.10.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-test-framework</artifactId>
        <version>4.10.2</version>
    </dependency>
    <!-- 创建索引时,需要创建倒排索引信息,创建倒排需要分词 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-analyzers-common</artifactId>
        <version>4.10.2</version>
    </dependency>
    <!--  如果用户的输入的关键词是个组合词,或者一个句子:为什么打雷不下雨? -->
    <!-- 用来解析用户的查询意图 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>4.10.2</version>
    </dependency>
 </dependencies>

Lucene 创建索引过程

  • 创建索引过程,StringFiled 不分词 TextFiled分词

    @Test
     public void createIndex() throws IOException {
    
     //1. 创建索引编辑器  
        Directory d = FSDirectory.open(new File("index"));
        Analyzer analyzer =new StandardAnalyzer();
        IndexWriterConfig conf =new IndexWriterConfig(Version.LATEST, analyzer );
        IndexWriter indexWriter = new IndexWriter(d, conf);
    
     //2. 对于文件创建索引   
    
        Document document = new Document();
        //StringField不分词 StringText 分词
        document.add(new StringField("title", "深度剖析百度完败O2O的前因后果", Store.YES));
        document.add(new StringField("author_name", "财经十一人",  Store.YES));
        document.add(new StringField("content", "虎嗅注:本文转自微信公众号“财经十一人”(ID:caijingEleven),作者:张珺。 百度决意痛斩O2O,是从任旭阳回归开始。 2016年中,百度董事长兼首席执行官李彦宏紧急召回任旭阳,接替百度前战略顾问何海文。任旭阳是以私人关系回来帮李彦宏,本身还在外创业,他兼任百度首席顾问一职。回归后,任的一项关键举措是说服李彦宏放弃了O2O战略:百度糯米与大搜进一步整合;百度外卖寻求投资和出售。 任旭阳是百度元老,参与百度早期创业十年,离职后仍和李彦宏保持不错的私交。李彦宏曾评价他,在工作中表现出“正直的人品、对公司业务的深刻理解、优秀的管理能力及对发现和培养人才的重视”。 在百度内部,O2O最积极的鼓吹者是百度前战略顾问何海文、百度前战略部副总裁金宇和百度前技术副总裁刘骏——前两者在战略和投资层面发挥影响,后者在执行层面。2015年7月,金宇接受采访曾说:“O2O是百度的孟良崮高地,百度会不惜一切代价打下来。” 但2016年下半年以来,这三位高层的人事动向隐含了百度战略思路转换。2016年7月,何海文被传离职。2016年9月,刘骏被传免去百度外卖董事长一职。2017年5月,金宇转岗,任百度资本合伙人。以上高层变动被外界认为是百度O2O迎来全面整肃的重要标志。 任旭阳回归后,不仅重新梳理公司战略,放弃O2O,还参与了百度外卖的早期出售洽谈。此外,他提名李彦宏夫人任董事长特别助理。任旭阳在2017年1月陆奇出任百度集团总裁、COO后逐步淡出。公开资料显示,任协助百度资本人才招募。 在陆奇到来和马东敏复出之前,任旭阳完成了百度最后一棒的交接。任的出现也许不是决定百度外卖剥离的根本因素,但却代表百度在这个关键节点上推动改革的意志和决心。 美团的三个offer 自2014年6月1日上线,百度外卖经历了从低谷到高潮再到衰落的抛物型曲线。 一位百度外卖离职中层对《财经》记者回忆:起初大家持怀疑态度,认为百度缺乏2B的基因,但不到一年时间,百度外卖势如破竹,迅速成为市场三强之一。“大家看到了巨大的希望、巨大的可能性。” 百度对O2O的狂热在2015年6月30日达到高点。这一天,李彦宏出席百度糯米O2O生态战略发布会,宣称账上还有500亿元,要砸200亿元到O2O。一个月后,百度推出“航母计划”,意在开放百度资产给外部投资者,而百度外卖被称作“航母计划先锋队”,承载厚望。2015年7月百度外卖分拆,独立完成2.5亿美元的A+轮融资。 上述离职中层说,当时外卖的核心团队成员找到他,他没有丝毫犹豫就和总部解约,单枪匹马到百度外卖组建团队。百度外卖门庭若市,很多百度员工想转岗过来,甚至一度因为人太多关闭了转岗通道。百度外卖员工全员持股,内外士气高昂。 百度外卖的早期成功主要归因于对白领市场的精准定位,倚靠百度的强大品牌,快速与高端餐饮企业建立联系。据多家数据机构报告,百度外卖在白领市场份额最高达到33%。 O2O市场格局改变的标志性事件是2015年10月8日大众点评与美团网合并。2016年1月,美团点评完成金额超过33亿美元的首次融资,该轮融资后公司估值超过180亿美元。 一位和几家公司都有深度接触的资深人士告诉《财经》记者,在合并之前,场内选手都已经交互谈过一轮。美团网彼时收到了三个offer:第一,拿百度的钱与糯米和百度外卖合并;第二,拿阿里的钱对抗点评和糯米;第三,拿腾讯的钱与点评合并。虽然在此之前阿里已经是美团的股东,但最终美团选择了与腾讯结为盟友,因为与前者业务重合度高,不易保持独立发展。 这次合并的影响远比想象中深远。美团点评合并后市场份额近80%,在团购市场形成垄断地位。此外,阿里和美团点评关系产生裂隙,为应对其合并,阿里重新扶植口碑,并在2016年4月以12.5亿美元投资饿了么。 在三个offer中,最不出意料的是美团没有拿百度的钱。一位熟悉美团点评的人士说,不管从资本、流量、软实力还是开放的心态,腾讯都是更好的选择。 “美团点评成立后拿了33亿美元,事实上对标了百度的200亿元,百度肯定认识到他们说的这个200亿元促使了美团点评的合并,以及能融到那么大一笔钱。”上述资深人士说,“200亿元事实上是给第一名在背书。” “从美团点评合并那一瞬间开始,大家就开始紧张,等到饿了么融资12.5亿美元,证明阿里入局外卖了,那时候百度外卖的融资额不增加,内部开始低迷。”上述离职中层说。 主舰开走了 “百度外卖的命运从来不掌握在自己的手上。”一位百度外卖员工说,“这是一个舰队,如果说百度这艘主舰忽然要转向,外卖就是一个冲锋艇,做什么都是没有意义的。”此时,大百度层面已经陆续开展一系列动作。 2016年中,任旭阳回归劝说李彦宏放弃O2O,与外界传言左右百度外卖出售的是百度执意打包糯米不同,百度从来没有要出售糯米的打算。任旭阳认为糯米可以保留,但全面转型广告平台,以盈利为目的。在阿里、腾讯疯狂注资的背景下,百度外卖跻身前二再无希望,于是决意出售。 百度集团层面在此时做了三件事: 第一,派驻CSO(首席战略官)启动百度外卖新一轮融资——2016年8月,前瑞士信贷董事总经理韦迪加盟百度外卖出任CSO; 第二,任旭阳主导寻求买家,先后谈判的买方有美团、顺丰和饿了么,马东敏复出后接棒; 第三,2016年7月开始百度外卖降低补贴,并派驻CFO(首席财务官)控制预算——2017年1月,小米原高管张金玲加盟百度,担任百度资本及百度外卖CFO,向百度CFO李昕晢汇报。 然而,在之后的大半年时间里,百度外卖既没有融到钱,也没能找到合适的买家,却因为缩减预算导致市场份额骤减,估值随之下滑。 百度外卖分拆以来有过两次融资:2015年7月,由汉能投资、百度和汉景家族办公室投资2.5亿美元的A+轮;2016年3月,由君同资本投资亿元及以上美元的B轮。这三四亿美元相对美团点评的,加之“一揽子协议”未果,在两个月前这场谈判也告吹。 最终2017年8月百度外卖以8亿美元的价格卖给饿了么。其中,百度外卖作价5亿美元(3亿美元现金+2亿美元等值股票),百度打包流量入口资源给饿了么,作价3亿美元。这一价格较此前24亿美元的估值缩水了三分之二。 “一场幻梦破灭了。”前述百度外卖离职中层说。 幕后风云 竞争态势的更迭和集团态度的转变组成了百度外卖兴衰的外部环境。再来看组织内部,一系列的人事变动说明其走到今日早有预兆。 百度外卖孵化自百度LBS(基于位置的服务)事业部,最早的创始成员包括巩振兵(现任百度外卖CEO)、王莆中(现任美团点评副总裁兼外卖和配送事业部总经理)和陈锦晖(现有赞公司渠道副总裁)。据两位百度外卖离职高层向《财经》记者透露,王莆中是百度外卖的一号员工,他拉拢巩振兵的原因是看中后者对李彦宏的触达力。 巩振兵2003年加入百度,历任百度渠道大区总监、全国渠道总监、北京分公司总经理,在2014年轮岗至百度LBS事业部。内部人称,作为“,陈青返回公司,并在2017年5月提拔为COO。陈锦晖担任巩振兵七年秘书,本和陈青同级,在内部更受认可,汇报关系改变后不服出走。 另一名离职高层人士表示,百度外卖最大的战略失误在2015年下半年美团和点评刚合并,那是美团点评最虚弱的时候,百度没有把主营业务配送的优势发挥到极致,而是提前去控制成本、追求一些不切实际的体验,比如生态厨房、早餐、生鲜等,错失良机。 不过他说:“如果给百度外卖的失败排序,第一是资源投入,第这样,百度的O2O达到终点,接下来将奔赴新的征程。下一站,AI。 未来面前,你我还都是孩子,还不去下载 虎嗅App 猛嗅创新!", Store.YES));
        document.add(new StringField("article_time", "2017-09-08 18:24", Store.YES));
        document.add(new StringField("article_share", "创业维艰", Store.YES));
        document.add(new TextField("article_pl", "评论8", Store.YES));  //分词
        document.add(new StringField("num", "22", Store.YES));
        document.add(new StringField("url", "https://www.huxiu.com/article/213867.html", Store.YES));
    
        indexWriter.addDocument(document); //内容中的数据提交到硬盘
        indexWriter.commit();
        indexWriter.close();

    }

使用Luke工具查看索引库

  • 这个工具可以用来查看对应的词条




Lucene 查询索引过程

@Test
public  void searchIndex() throws IOException {

    //1. 创建索引查询器
        Directory directory = FSDirectory.open(new File("index"));
        IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(directory));
    //2. 设置用户的查询关键字 
        String keyword ="财经十一人";
    //3. 根据词条进行查询  
        Query query = new TermQuery(new Term("author_name", keyword)); //关键字转为Term对象,指定关键字要查询的字段
        Integer n = Integer.MAX_VALUE;
        TopDocs res =   indexSearcher.search(query, n);
        System.out.println("查询返回多少条数据                  " + res.totalHits); 
        ScoreDoc[] scoreDocs = res.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {

             System.out.println("维护在lucene内部的文档编号:"+scoreDoc.doc);
             //对于单篇文章来说分数越高 说明这个关键字在文章中很重要
             //对于多篇文章来说 分数越低 说明这个关键字很稀少    因此分数的高低决定的是相关性
             System.out.println("当前文档的得分:"+scoreDoc.score);

             //获取单篇文章的信息
             Document doc = indexSearcher.doc(scoreDoc.doc);
                System.out.println("id:   "+doc.get("id"));
                System.out.println("title:   "+doc.get("title"));
                System.out.println("author:   "+doc.get("author_name"));
                System.out.println("createTime:   "+doc.get("article_time"));
                System.out.println("content:   "+doc.get("content"));
                System.out.println("url:   "+doc.get("url"));
        }
}

项目中使用ikanalyzer分词器

lucene的花式查询

// 通过两次置换,能够得到一个词条
     Term term = new Term("content","大据数");
     FuzzyQuery query = new FuzzyQuery(term);

     //通过前缀查询
     PrefixQuery query1 = new PrefixQuery(new Term("content", "大"));
     WildcardQuery query2 = new WildcardQuery(new Term("content","大*")); 

     BooleanQuery query3 = new BooleanQuery();
     WildcardQuery wildcardQuery = new WildcardQuery(new Term("content", "大*"));
     query3.add(wildcardQuery, Occur.MUST);

         //前置查询
//       PrefixQuery prefixQuery = new PrefixQuery(new Term("content", "金"));
//       prefixQuery.add(prefixQuery, Occur.MUST); 
//       
         //重要:在大多数情况下,用户的输入不一定是一个词条,
         //所以我们需要对用户的输入进行分词,将输入编程多个词条之后进行查询。
//       Analyzer analyzer = new IKAnalyzer();
//       QueryParser queryParser = new QueryParser("content", analyzer);
//       Query query4 =queryParser.parse("学习大数据");
//
//       //重要:有时候业务会提供多个字段供用户选择,店铺,商家,旺旺。
//       MultiFieldQueryParser multiFieldQueryParser 
//       = new MultiFieldQueryParser(new String[]{"title","content"},new IKAnalyzer());
//       Query query =multiFieldQueryParser.parse("学习大数据");

使用lucene开发一个搜索引擎

  • 对外开发一个controller,这个controller提供两个方法
    • init:读取数据库的数据,创建索引
      • ———dao————-
      • mysql jdbc DataSource
      • jdbctemplate mybatis访问
      • select * from huxiu_article;
      • ———-service———–
      • 得到数据库查询的结果,并封装到list集合当中
      • 迭代list中的元素,将每个元素封装一个document对象
        • 调用indexWriter.add(doc)创建索引
        • 调用indexWriter.commit()
      • 关闭indexWriter.close()
    • query:查询方法,主要接受用户输入的关键字。
      • ——–controller———
      • 获取数据
      • ————service——–
      • 将用户的关键词封装成一个query对象
        • 使用QueryParser对用户输入的关键词进行分词
        • indexSearcher.search(query,integer.max)
      • 得到索引库的返回值,封装成一个list对象。
      • 返回list对象给页面
      • 页面通过jstl等等技术,进行展现。
网友评论