下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

简谈 Lucene

作者:课课家教育     来源: http://www.kokojia.com点击数:746发布时间: 2018-02-10 09:30:11

标签: 互联网搜索引擎lucene数据库

  随着互联网的快速发展,网路舆论对社会生活的影响越来越大,网路口碑研究也逐渐形成一个新兴行业。有效的网络口碑研究,需要全方位地倾听网民的声音。信息检索技术的应用,有效地提高了网络口碑研究的工作效率。Lucene 作为当今最知名的开源信息检索库,被广泛应用于各种与全文检索相关的项目中。本文简单的介绍Lucene,供大家参考讨论学习。
  1、Lucene是什么?
  Apache Lucene是一个高性能(high-performance)的全能的全文检索(full-featured text search engine)的搜索引擎框架库,完全(entirely)使用java开发。它是一种技术(technology),适合于(suitable for)几乎(nearly)任何一种需要全文检索(full-text search)的应用,特别是跨平台(cross-platform)的应用。它在系统的地位,相当于一个主要用来全文检索 简谈 Lucene_互联网_搜索引擎_lucene_数据库_课课家教育
  Lucene与数据库有许多相通之处,以下我们做个简单对比:
Lucene_数据库_查询
  Lucene与倒排索引(Inverted index)
  我想很多人在用数据库时,都遇到过这种类似的情况:查找含‘奥运会’这个词的数据, 一般都用 LIKE '%奥运会%' 作为条件的SQL语句进行。 这种解决方法,在数据量很大时,存在严重的性能问题。因为一般的数据库索引,对这种查询没有任何帮助。 Lucene作为主要应用于全文检索领域的库,引入了一种倒排索引的技术。
  ● 相关概念
  Term = Field.name + Token.text
  Token 分词后的最小单位,如:2008年、奥运会、将、在、北京、举行
  Document 每个Document有个唯一的内部编号ID(int类型),重建索引时ID可能变化
  ● 倒排索引文件格式(示意图)
  Term1 DocID1 DocID2 DocID3 …
  Term2 DocID1 DocID2 DocID3 …
  … …
  从以上格式中不难看出,利用这种索引文件,可以迅速定位到包含‘奥运会’这个词的所有文章。
  Lucene 通过一些简单的接口(simple API)提供了强大的特征(powerful features):
  1)可扩展的高性能的索引能力(Scalable, High-Performance Indexing)
  超过20M/分钟的处理能力(Pentium M 1.5GHz)
  很少的RAM内存需求,只需要1MB heap
  增量索引(incremental indexing)的速度与批量索引(batch indexing)的速度一样快
  索引的大小粗略(roughly)为被索引的文本大小的20-30%
  2)强大的精确的高效率的检索算法(< /strong>Powerful, Accurate and Efficient Search Algorithms)
  分级检索(ranked searching)能力,最好的结果优先推出在前面
  很多强大的query种类:phrase queries, wildcard queries, proximity queries, range queries等
  支持域检索(fielded searching),如标题、作者、正文等
  支持日期范围检索(date-range searching)
  可以按任意域排序(sorting by any field)
  支持多个索引的检索(multiple-index searching)并合并结果集(merged results)
  允许更新和检索(update and searching)并发进行(simultaneous)
  3)跨平台解决方案(Cross-Platform Solution)
  以Open Source方式提供并遵循Apache License,允许你可以在即包括商业应用也包括Open Source程序中使用Lucene
  100%-pure Java(纯Java实现)
  提供其他开发语言的实现版本并且它们的索引文件是兼容的
  Lucene API被分成(divide into)如下几种包(package)
  1)org.apache.lucene.analysis
  定义了一个抽象的Analyser API,用于将text文本从一个java.io.Reader转换成一个TokenStream,即包括一些Tokens的枚举容器(enumeration)。一个TokenStream的组成(compose)是通过在一个Tokenizer的输出的结果上再应用TokenFilters生成的。一些少量的Analysers实现已经提供,包括StopAnalyzer和基于语法(gramar-based)分析的StandardAnalyzer。
  2)org.apache.lucene.document
  提供一个简单的Document类,一个document只不过包括一系列的命名了(named)的Fields(域),它们的内容可以是文本(strings)也可以是一个java.io.Reader的实例。
  3)org.apache.lucene.index
  提供两个主要类,一个是IndexWriter用于创建索引并添加文档(document),另一个是IndexReader用于访问索引中的数据。
  4)org.apache.lucene.search
  提供数据结构(data structures)来呈现(represent)查询(queries):TermQuery用于单个的词(individual words),PhraseQuery用于短语,BooleanQuery用于通过boolean关系组合(combinations)在一起的queries。而抽象的Searcher用于转变queries为命中的结果(hits)。IndexSearcher实现了在一个单独(single)的IndexReader上检索。
  5) org.apache.lucene.queryParser
  使用JavaCC实现一个QueryParser。
  6)org.apache.lucene.store
  定义了一个抽象的类用于存储呈现的数据(storing persistent data),即Directory(目录),一个收集器(collection)包含了一些命名了的文件(named files),它们通过一个IndexOutput来写入,以及一个IndexInput来读取。提供了两个实现,FSDirectory使用一个文件系统目录来存储文件,而另一个RAMDirectory则实现了将文件当作驻留内存的数据结构(memory-resident data structures)。
  7)org.apache.lucene.util
  包含了一小部分有用(handy)的数据结构,如BitVector和PriorityQueue等。
  2、hello word
  下面是一段简单的代码展示如何使用Lucene来进行索引和检索(使用JUnit来检查结果是否是我们预期的):
  // Store the index in memory:
  Directory directory = new RAMDirectory();
  // To store an index on disk, use this instead:
  //Directory directory = FSDirectory.getDirectory(”/tmp/testindex”);
  IndexWriter iwriter = new IndexWriter(directory, analyzer, true);
  iwriter.setMaxFieldLength(25000);
  Document doc = new Document();
  String text = “This is the text to be indexed.“;
  doc.add(new Field(“fieldname“, text, Field.Store.YES,
  Field.Index.TOKENIZED));
  iwriter.addDocument(doc);
  iwriter.optimize();
  iwriter.close();
  // Now search the index:
  IndexSearcher isearcher = new IndexSearcher(directory);
  // Parse a simple query that searches for ”text”:
  QueryParser parser = new QueryParser(“fieldname“, analyzer);
  Query query = parser.parse(“text“);
  Hits hits = isearcher.search(query);
  assertEquals(1, hits.length());
  // Iterate through the results:
  for (int i = 0; i < hits.length(); i++) {
  Document hitDoc = hits.doc(i);
  assertEquals(“This is the text to be indexed.“, hitDoc.get(“fieldname“));
  }
  isearcher.close();
  directory.close();
  为了使用Lucene,一个应用程序需要做如下几件事:
  1)通过添加一系列Fields来创建一批Documents对象。
  2)创建一个IndexWriter对象,并且调用它的AddDocument()方法来添加进Documents。
  3) 调用QueryParser.parse()处理一段文本(string)来建造一个查询(query)对象。
  4) 创建一个IndexReader对象并将查询对象传入到它的search()方法中。
  3、 Lucene Roadmap
Lucene Roadmap_数据库_查询
  4、使用lucene的常见问题与建议
  ● 中文分词库: 网上可用的免费中文分词库有 IKAnalyzer(免费但不开源)、Stanford(开源但需自行封装lucene接口)
  ● 组合查询条件:通过使用QueryParser类,可以支持AND、OR等多种组合条件
  ● 结果排序: lucene默认按评分排序,通过结合Sort与SortField类,可指定多个排序字段与升降序,排序字段的索引类型必须为UN_TOKENIZED
  ● 分布式查询: 通过lucene提供的RemoteSearchable类,可以实现分布式查询
  ● 并行查询: 当分布式有多个节点时,可以通过ParallelMultiSearcher进行并行,以提高检索性能
  ● 分词与查询: 当索引中以‘奥运会’作为一个词时,通过‘奥运’是无法检索到相应结果的。这个问题可以通过修改检索条件或分词时按较小粒度进行处理
  ● 数字与日期: 因lucene索引库一律按String类型处理,因此数字日期应补0,使能够正确按字符串比较排序
  ● 字段索引类型:email日期等无需分词的字段,索引类型应选择UN_TOKENIZED
  ● 线程安全性: 应保证同时只有一个线程对lucene库进行写操作,可以有多个线程对lucene库进行读操作

赞(25)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程