lucene算法
Ⅰ java 怎么用lucenes进行分词
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
/**
* 使用IKAnalyzer进行Lucene索引和查询的演示
* 2012-3-2
*
* 以下是结合Lucene4.0 API的写法
*
*/
public class LuceneIndexAndSearchDemo {
/**
* 模拟:
* 创建一个单条记录的索引,并对其进行搜索
* @param args
*/
public static void main(String[] args){
//Lucene Document的域名
String fieldName = "text";
//检索内容
String text = "IK Analyzer是一个结合词典分词和文法分词的中文分词开源工具包。它使用了全新的正向迭代最细粒度切分算法。";
//实例化IKAnalyzer分词器
Analyzer analyzer = new IKAnalyzer(true);
Directory directory = null;
IndexWriter iwriter = null;
IndexReader ireader = null;
IndexSearcher isearcher = null;
try {
//建立内存索引对象
directory = new RAMDirectory();
//配置IndexWriterConfig
IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_40 , analyzer);
iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
iwriter = new IndexWriter(directory , iwConfig);
//写入索引
Document doc = new Document();
doc.add(new StringField("ID", "10000", Field.Store.YES));
doc.add(new TextField(fieldName, text, Field.Store.YES));
iwriter.addDocument(doc);
iwriter.close();
//搜索过程**********************************
//实例化搜索器
ireader = DirectoryReader.open(directory);
isearcher = new IndexSearcher(ireader);
String keyword = "中文分词工具包";
//使用QueryParser查询分析器构造Query对象
QueryParser qp = new QueryParser(Version.LUCENE_40, fieldName, analyzer);
qp.setDefaultOperator(QueryParser.AND_OPERATOR);
Query query = qp.parse(keyword);
System.out.println("Query = " + query);
//搜索相似度最高的5条记录
TopDocs topDocs = isearcher.search(query , 5);
System.out.println("命中:" + topDocs.totalHits);
//输出结果
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < topDocs.totalHits; i++){
Document targetDoc = isearcher.doc(scoreDocs[i].doc);
System.out.println("内容:" + targetDoc.toString());
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} finally{
if(ireader != null){
try {
ireader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(directory != null){
try {
directory.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Ⅱ 为什么说lucene的算法是最好的
对那些刚接触Lucene的人来说,这里是使用它的关键:Apache Lucene是一个由java编写的高性能,全方位的单词搜索引擎库。在批评它之前,我必须承认Lucene是一个高性能的划词搜索引擎。几年来,Lucene已经被看作是用java编写的嵌入式搜索引擎中的一等公民。它的声誉每日剧增,并且仍然是开源java搜索引擎中的最佳。每个人都在说:“Doug Cutting做了一项伟大的工作”。然而,最近的几个月内,开发的进程变得缓慢,我认为Lucene将不会满足现代的文档处理需求。不要把东西搞糟:我不是搜索引擎开发者,我只是个开发者,使用搜索引擎,来提供合适信息的检索科技。这贴是讨论为什么对未来的开发者而言,Lucene不是最好选择,至少对我们而言如此,并且情况并没有得到改变。我们列出Lucene的局限性:Lingway公司基于语意来生成复杂的查询。例如当你正在查找关于“中东地区冲突”的文章,你也许还需要找关于“伊拉克战争”文章。在上面这个用例中,“战争”和“伊拉克”分别是“冲突”和“中东”的扩展。我们使用一种技术能分析你的查询,产生相应的最合适的扩展,为它们生成查询。然而,为了得到相关的结果,这些还是不够的:通过Lucene实现的类似Google的等级或是经常变化积分的并不能满足语意级别积分。例如,一个包含“中”和“东”短语,但是被超过一个以上的单词隔开,这种情况并不是我们想要查找的。更重要的是,相对常规的单词,我们应该给扩展更低的分数。比如,我们应该给“中东地区冲突”这个短语更高的分数,而不是“伊拉克战争”。在Lingway公司,我们认为这种文章相关性技术是一种未来的搜索引擎。Google在文章搜索上做的很出色。但我们想要的却是最相关的文章。但是,大部分的当代搜索引擎都没有对这样复杂查询做相关的设计…Lucene被wikipedia使用,如果你注意到当你查询查过一个单词时,大多数的查询结果并不是由关联的…为了演示需求,这里有一个Lingway公司即将上线的KM3.7产品的界面截图。这里我们用法语写一个查询,用来查找那些同样主题,而用英语写的文章。注意,这可不仅仅是简简单单的翻译,我们称之为语言交叉模式:注意到那些绿色的匹配:chanteur变成了singer,但是我们也发现singing被匹配了。同样情况流行乐成为蓝调的扩展。6大理由不选用Lucene6. 没有对集群的内置支持。如果你创建集群,你可以写出自己对Directory的实现,或是使用Solr或者使用Nutch+Hadoop。Solr和Nutch都支持Lucene,但不是直接的替代。Lucene是可嵌入的,而你必须支持Solr和Nutch..我认为Hadoop从Lucene团队中产生并不惊讶:Lucene并不是通用的。它的内在性决定了对大多数场合来说它是非常快速的,但是对大型文档集合时,你不得不排除Lucene。因为它在内核级别上并没有实现集群,你必须把Lucene转换到别的搜索引擎,这样做并不直接。转换到Solr或者Nutch上的问题会让你遇到许多不必要的麻烦:Nutch中的集成crawling和Solr中的检索服务。5.跨度查询太慢这对Lingway公司来说可能是个特殊的问题。我们对跨度查询有很强要求,Lucene检索结构已经开始添加这一细节,但它们当初可没这么想。最基础的实现导致了复杂的算法并且运行缓慢,尤其是当某些短语在一份文档中重复了许多次出现。这是为什么我倾向说Lucene是一个高性能的划词检索引擎当你仅仅使用基本的布尔查询时。4.积分不能被插件化Lucene有自己对积分算法的实现,当条件增加时使用Similarity类。但很快它显示出局限性当你想要表示复杂的积分,例如基于实际匹配和元数据的查询。如果你这样做,你不得不继承Lucene的查询类。因为Lucene使用类似tf/idf的积分算法,然而在我们遇到的场合,在语意上的积分上Lucene的积分机制并不合适。我们被迫重写每一个Lucene的查询类使得它支持我们自定义的积分。这是一个问题。3.Lucene并非良好设计作为一个系统架构师,我倾向认为(1)Lucene有一个非常糟糕的OO设计。虽然有包,有类的设计,但是它几乎没有任何设计模式。这让我想起一个由C(++)开发者的行为,并且他把坏习惯带到了java中。这造成了,当你需要自定义Lucene来满足你的需求(你将来必定会遇到这样的需求),你必须面对这样的问题。例如:几乎没有使用接口。查询类(例如BooleanQuery,SpanQuery,TermQuery…)都是一个抽象类的子类。如果你要添加其中的一个细节,你会首先想到写一个接口来描述你扩展的契约,但是抽象的Query类并没有实现接口,你必须经常的变化自己的查询对象到Query中并在本地Lucene中调用。成堆的例子如(HitCollecor,…)这对使用AOP和自动代理来说也是一个问题. 别扭的迭代实现.没有hasNext()方法,next()方法返回布尔类型并刷新对象内容.这对你想要保持对迭代的元素跟踪来说非常的痛苦.我假定这是故意用来节省内存但是它又一次导致了算法上的杂乱和复杂. 2.一个关闭的API使得继承Lucene成为痛苦在Lucene的世界中,它被称之为特性。当某些用户需要得到某些细节,方针是开放类。这导致了大多数的类都是包保护级别的,这意味着你不能够继承他们(除非在你创建的类似在同一个包下,这样做会污染客户代码)或者你不得不复制和重写代码。更重要的是,如同上面一点提到的,这个严重缺乏OO设计的结构,一些类应该被设为内部类却没有,匿名类被用作复杂的计算当你需要重写他们的行为。关闭API的理由是让代码在发布前变得整洁并且稳定。虽然想法很光荣,但它再一次让人感到痛苦。因为如果你有一些代码和Lucene的主要思路并不吻合,你不得不经常回归Lucene的改进到你自己的版本直到你的补丁被接受。然而当开发者开始越来越长的限制API的更改,你的补丁很少有机会被接受。在一些类和方法上加上final修饰符会让你遇到问题。我认为如果Spring框架有这样的限制,是觉不会流行起来。1. Lucene搜索算法不适合网格计算Lucene被写出来的时候硬件还没有很大的内存,多处理器也不存在。因此,索引结构是被设计成使用线性的内存开销很小的方式。我花了很长的时间来重写跨度查询算法,并使用多线程内容(使用双核处理器),但是基于迭代器的目录读取算法几乎不能实现。在一些罕见的场合你能做一些优化并能迭代一个索引通过并行方式,但是大多数场合这是不可能的。我们遇到的情况是,当我们有一个复杂的,超过50+的内嵌跨度查询,CPU还在空闲但I/O却一直忙碌,甚至在使用了RAMDirectory.有没有替代品?我认为最后一个观点充满疑问:Lucene到达了它的极限当它在现在硬件基础的条件下,检索大型数据集合时。那就是我为什么寻找下一个可以替代Lucene的出现。在阅读了博客目录和 Wikia的讨论后,我发现并没有很多的替代品。然而我最后推荐一个有希望的方案:MG4J。它有一个良好的面向对象设计,性能良好的检索(索引比Lucene慢),内存开销上也很小,达到10倍于Lucene速度的跨度查询,在我的跨度查询基准上,并且是原生上支持集群。同样它也内置了负载平衡,而Lucene最近才加入这项功能并且还是实验性质的。然而MG4J仍然缺少一些特性例如简单的索引指数,文档移除和更简单的使用索引处理。让我感到高兴的是我可以自定义Lucene上的功能在MG4J上只需花几个小时,而在Lucene上却需要数天。我认为对开源的搜索引擎来说仍然有发展空间,它不是通过单台电脑用有限的内存来索引批量文档,而是通过透明的分布式索引来提供对大型数据集合检索更为快捷的答案。你不必利用应用来获得集群特性。Lucene对第一类搜索引擎有了很好的实现,单我认为它并不符合我们的需求:在一个合理的时间内找到最佳的答案。基于tf/idf的搜索算法和google的等级并不是未来搜索引擎的趋势。实现对原数据和语义的复杂查询并找出相关的信息,这是Lingway公司(通过Lucene和其他搜索引擎技术)所作的,不过它要求有更多支持新硬件的新技术。使用Lucene的一个好理由无论我如何指责Lucene,它仍然是java开源解决方案中的最佳实现。
Ⅲ 怎么用lucene判断两篇文章的相似度 java
用算法中的求最大相似子字符串的方法LCS或许可以,它可以找到两个字符串中最大相似的子字符串。
Java code
/*
* @author talent_marquis<甜菜侯爵>
* Email: [email protected]
* Copyright (C) 2007 talent_marquis<甜菜侯爵>
* All rights reserved.
*/
package ustc.mse.algorithms.dynamicProgramming;
/*
* LCS, Longest-Common-Subsequence
*/
public class LCS
{
public enum DIRECTION{ TOP, TOP_LEFT, LEFT };
private char[] first;
private char[] second;
private int[][] lcsTable;
private DIRECTION[][] lcsAssistTable;
private int lcsLength;
private String lcs_str, lcsMatrix_str, lcsAssistMatrix_str;
private StringBuffer str_buffer;
public LCS( String str1, String str2 )
{
first = str1.toCharArray();
second = str2.toCharArray();
lcsTable = new int[ first.length + 1 ][ second.length + 1 ];
lcsAssistTable = new DIRECTION[ first.length + 1 ][ second.length + 1];
lcs_str = null;
Ⅳ Lucene是什么
Lucene针对中文单字为词,“我是学生”在standardAnalyzer分割下,分为“我”,“是”,“学”,“生”。
车东做了CJKAnalyzer可以分为“我是”,“是学”,“学生”。
你也可以用Dijkstra算法来自己做一个,源代码向家立要,他和我写过《Lucene分析与应用》,他会告诉你去如何下载这个代码,这种分词都是有经验值的,也就是说“学生”,已经是分割过的,就是有字典存在。
不配合字典你再想一想,自然语言是什么?是人类的交谈工具吧,有没有规律哪?频率,位置依赖关系,但是不管如何,人类自己要能明白,没有人类自身的经验,就别谈“分词”,“字典”。
分词与Lucene关系不大,它只是输入,虽然也会影响索引,与效率,效能,但是Lucene与你谈论的问题关系不太大。
Ⅳ (2007-5-22更新)Lucene(Nutch)距离商业文本搜索引擎还有多远
注(2007-5-22):最新一次更新的时候,我再次研究了一下Lucene,读完了Lucene In Action,并且实际的使用Lucene构建了一个小型的搜索系统之后,我感觉到很惭愧,因为我一直对Lucene有不满的心理,认为它做的不好(可能受了国内的某些使用Lucene构建搜索引擎的网站的影响,因为他们构建的都很差,现在想来,可能是他们和我一样没有真正深入理解Lucene)。现在我才发现,Lucene的作者在大方向上考虑问题的全面比我要好很多(虽然有些功能我不知道是否真的有用)。现在我的感受是:1)Lucene对查询的理解十分深入,几乎什么样的查询需求它都考虑到了。而对于普通的商业搜索引擎来说(比如,网络),它们只是考虑到了布尔查询模式,远不及Lucene里面的查询方式多;2)Lucene对过滤和排序的处理已经能够满足90%的要求了。过滤可以把不需要的结果删除,而排序则可以根据某个域的值来进行结果排序。基本的垂直搜索引擎,是必须这些功能的,因为这些功能能够缩小查询的结果集,提高用户体验。而网络等商业搜索引擎显然是不需要(或者没有提供)这些功能的。3)Lucene的分值计算效果不错。抛开基本的IR的那些标准的分值计算算法不说(谁都知道总体上Lucene使用了简化的向量模型,但实际上Lucene在布尔模型查询上面也使用了简化的扩展布尔模型分值计算公式),Lucene支持了大部分额外的基于经验的分值计算。举例来说,查询“中国北京”的时候,以下是几个文档的实际排序(直接解析这个查询短语是得不到这个结果的,见第4点):中国北京北京中国中国可爱北京 北京属于中国4)Lucene不提供真正的查询串解析。基于文法的查询串解析,一个严重的结果就是容错太差,所以,我们几乎可以认为Lucene并不提供实际有用的查询串解析。所以呢,上面我们说的“中国北京”需要您自己把它解析为: PhraseQuery query = new PhraseQuery(); query.add(new Term("name","中国")); query.add(new Term("name","北京")); query.setSlop(1000);然后才会有上面的那个结果。所以,使用Lucene的第一步是提供您自己的查询串解析器。5)理解Lucene的算法限制。Doug Cutting不是神仙,他也无法解决算法的问题,所以呢,几乎所有算法的限制都会在Lucene里面出现,比如,RangeQuery查询速度极慢,Sort排序需要很大的内存来缓冲Field的值。这些并不是Doug Cutting的错,而是算法的限制,我想应该没有人能够解决这类问题吧?(虽然从IR中我们知道RangeQuery可以使用B+树等结构来加快查询,不过,我们似乎不能够责怪Lucene,因为Lucene使用的是紧凑的文件结构,难以支持B+树结构) 如果您真的需要考虑这些问题的话,您可以自己修改Lucene的代码或者提供额外的扩展。6)理解Lucene的其他限制。在实际应用的过程中,您会发现Lucene有各种各样的限制,在这里,我想提醒您2个问题:a)缓冲同步;b)写/读同步。Lucene的缓冲做的不好,您可以根据实际情况自己扩展,在扩展的时候,请时刻注意缓冲和实际数据同步的问题。写/读同步其实是Lucene自己的问题,在同时读写一个Directory的时候,写的数据并不会马上表现到读上面,所以呢,要么关闭写,要么自己缓冲写结果。Lucene是一个开源的基于java的搜索引擎,它只包含IR(Information Retrieve)部分。它即不是唯一的也不是最好的一个开源搜索引擎,更好的比如egothor,但是它是文档最全面和受到关注最多的一个。Nutch是基于Lucene并加入了分布式和Crawler部分的搜索引擎。在本文中,作者试图从掌握的知识范围谈论一下它们使用的技术和一般商业文本搜索引擎使用的技术之间的距离。因为作者水平有限,仅仅拥有2年不到的搜索研究和实践经验,不足之处请大家多多指教。谢谢。1 网络搜索引擎的构架一个专业的网络搜索引擎至少包含3部分,即抓取、处理和搜索。下面是它们的一般功能:抓取:抓取(蜘蛛、爬虫、crawler、spider等)程序负责爬行特定网络(也可能是整个网络),把网络上的页面和其它需要的文件下载到本地来。目前的难点是web2.0的普及导致的js分析和身份认证等问题。处理:处理(分类、信息抽取、数据挖掘、classify、information extraction、data mining等)程序对抓回来的页面进行分析,比如,对网站的内容进行分类、对新闻页面的新闻信息进行提取、页面模版生成、对各个网站之间的关系进行计算等等。搜索:搜索(information retrieve)程序负责把文档填充到数据库,然后根据查询字符串到数据库中寻找最相关的文档展现给用户。仅仅从搜索引擎的构架来看,Lucene(Nutch)缺失的一环是信息的处理。信息的处理恰恰是整个搜索引擎中最核心的技术。2 信息抓取网络信息抓取包含了网页抓取、文本文件抓取和其它文件抓取。对于使用http(还有https)等协议的网站来说,信息抓取的主要过程是:根据指定uri地址,进入第一个页面;分析页面构成,得到超链接地址,把地址加入到待下载链接中去;当还有未下载的链接时,下载对应页面,保存页面,并返回到第2步;所有链接都下载完毕,退出。普通的信息抓取一般可以被称为Spider,它利用基本的html页面分析器(比如,HtmlParser、NeckoHtml、JTidy等)来解析html页面,得到页面中的超链接。一般的说,一个Spider由以下2部分组成:http下载器。给定一个uri地址,http下载器负责把这个地址的数据下载回来。或许大家会认为这个很容易,其实不然。网络中的页面,除了http协议以外,https安全协议也是十分常用的一种协议。当你要下载的数据需要认证的时候,你还需要让你的下载器支持认证。当你下载的数据需要登录的时候,你还需要让你的下载器支持Cookie。所以,你的下载器仅仅支持http还是远远不够的。在这点上,Nutch还差得远。html页面解析器。html页面解析器并不是支持html页面就万事大吉了的,现在的很多页面其实使用的是xml的构建方法,虽然html和xml很像,但是,它们的tag名字显然有很大差别。除此以外,wap手机类页面也是你可能需要支持的页面。Nutch使用的是NeckoHtml或者JTidy。实际应用表明JTidy比较一般,但是NeckoHtml具有不错的效果。在开源的软件中,它应该算是最好的一个html页面解析器。然而,它和IE或者Mozilla这些浏览器的html parser比较起来,还是有一段距离的。除此以外,这类Spider仅仅只是把页面分析成了DOM树,它并不能够对基于ajax技术的web2.0页面进行有效处理。要想处理那些大量使用ajax技术或者大量运用js代码的页面数据,Spider需要的仍然是js处理能力。当然了,关于js的处理也可以被划分到数据处理部分去。3 信息处理似乎在Lucene(Nutch)面前谈论信息处理显得有点不专业,因为它们压根就不支持。但是,信息处理部分你还是可以自己编写后嵌入到Lucene(Nutch)里面去的。信息处理话题太大,作者没有这个胆量和水平对此妄加谈论,虽然这个是作者一直研究的主要方向。唯一可以肯定的就是,信息处理需要的知识至少有2点:1,机器学习(ML);2,自然语言理解(NLP)。前者典型的包括SVM、HMM等,后者包括HNC、知网等。笔者自信对ML有一定的理解,但是,对NLP的理解不太深入,还没有形成一个完整的解决方案。4 信息获取对信息获取的研究已经好多好多年了,多到那个时候作者都未出生。这部分主要分为2个步骤,第一个步骤是把文档填入到数据库(也就是所谓的构建索引);第二个部分就是根据用户输入得到一系列最相关文档(即所谓的搜索)。得到最相关文档无外乎就是比较2个文档的相似度。当用户输入一个字符串(即一个文档)之后,搜索引擎根据这个文档到数据库中寻找和它最相关的文档,然后返回给用户。实际搜索引擎必须考虑速度的问题,不可能像理论上说的那样去做。搜索的时候,一般有如下3步:查询字串解析。查询的组织方式有很多种,比如布尔查询等。一般商业文本搜索引擎支持的查询大约这样:“北京黄河 AND tom cat(OR 美丽-祖国)jerry + mouse”。即支持AND(+)、OR(|)、-、括号和引号的复合表达式。光解析还不行啊,你还得进行额外的优化,比如,对于“北京北京北京北京”这个串来说,它和“北京”的效果是一样的吧?Lucene在这个方面做了不少工作,只是,你仍然需要自己写一个更接近中文和商业搜索引擎的查询字串解析器。你可以根据需要,决定是把表达式优化为适合并行计算还是最小计算量的形式。 我们AND AND AND 他们 作为一个追求完美的人,作者实在无法接受这样无法忍受的“错误”。查询。查询的部分没有什么太多可以说的。有一点是,算法该优化的都没有优化。不过,对于一个处于初级开发中,并且开发人员缺乏的Project来说,这样就足够了。结果排序。Lucene使用的分值计算方法在比较接近于IR理论上使用的一些计算方法。可是,实际中的分值计算却比这个要麻烦很多。一个例子就是Lucene使用的方法没有考虑到查询词语之间的紧密位置。比如,对于“北京商店”和“北京 商店”来说,得到的前几个结果显然应该差别很大,这是因为前者更倾向于“北京”和“商店”这2个词语在一起的情况。要Lucene做到这一点其实也容易,只是,它会严重的降低搜索速度(几倍)。 实际应用中,还常常需要计算某些属性的值的权重。比如,新闻搜索里面,今天的新闻是不是应该比昨天的新闻权重大一点呢?Lucene未能支持这点。5 速度第一对于搜索引擎来说,速度绝对是第一个需要考虑的问题。信息抓取的速度显然不在软件能够解决的范围内,它只能通过增加带宽和多级更新策略来提高了。信息处理的速度不在本文的讨论之列。信息获取的时候,有2个地方需要考虑到速度:索引速度。索引速度包含索引的构建速度、文档的修改速度和文档的删除速度。在粗粒度上说,Nutch采用的基于MapRece策略的分布式索引构建方法是一个不错的构架。在细粒度上说,Lucene使用的内存缓冲和磁盘小索引合并的方法也是一个很好的构架。它们在构建索引上的表现都是令人称道的。在文档的删除上,Lucene使用的标记后再删除的方法是无可厚非的。在文档的修改和文档的追加上面,Lucene做的还差强人意。文档在修改的时候,唯一的办法就只能是先删除然后再追加。这点显然是不能令人满意的。查询速度。Lucene(Nutch)认为分布式的查询是不可取的,因为速度更慢。其实并不是速度慢,而是分布式查询需要一个快速的构架,这个构架涉及到搜索引擎的所有方面。暂时不是Nutch能够达到的。所以,Lucene(Nutch)的查询都是在一台机器上运行的。另外,Lucene因为它采用的分值计算方法的缘故,它不需要加载词语在文档中的位置信息,所以,它表面上看起来比其它搜索引擎快速了。其实是牺牲精度获得速度,另外,它自己使用的文件结构严重的制约了它的速度。没有引入缓冲是Lucene(Nutch)的另外一个严重失误。在这个构架里面,你可以自己构建一个查询结果缓冲(一级缓冲),但是,你很难构建一个基于词语的索引缓冲(二级缓冲)。这对于一个大搜索量的系统来说,是不可想象的。更何况普通商业搜索引擎还会有第三级缓冲。6 精度第二如果仅仅从Lucene(Nutch)支持的查询方式和分值计算来看,Lucene(Nutch)不存在精度的问题,因为它们都是计算了全部数据的。商业搜索引擎因为数据量过大的缘故,不得不使用一些估计的算法来减少磁盘数据的读取,这会导致精度的略微丢失。反过来说,Lucene无法支持大规模数据。7 效率第三这里说的效率主要是空间效率。比如,程序的内存占用和磁盘占用。Lucene使用了zlib压缩技术来压缩文档内容,还有使用了简单的压缩整数的方法。但是,它使用的压缩方法还是太少了,它少用压缩的结果是:1)文件结构和代码简单;2)查询速度变慢;3)索引segment合并快速;4)磁盘占用增加。同时,它几乎不用压缩也和它放弃缓冲有很大联系,因为压缩过的索引很容易放到内存里面,这点十分满足缓冲的空间需求。后记:因为作者对算法极其狂热,本文更多的是比较了开源搜索引擎Lucene(Nutch)和基本的商业搜索引擎之间在算法上的差别。为了让大家看的更明白,这里几乎没有提到任何算法。写的太多了,有空再增加。07.5.9 后记:根据最近的一些感悟,修改了本文。增加了一些认为重要的语句。
Ⅵ lucene 怎么实现去词根词缀
Lucene下引入ICTCLAS进行中文分词的实现方法
http://www.cnblogs.com/cy163/archive/2008/06/07/1215499.html
如何DIY一个Analyzer
咱们写一个Analyzer,要求有一下功能
(1) 可以处理中文和英文,对于中文实现的是单字切分,对于英文实现的是以空格切分.
(2) 对于英文部分要进行小写化.
(3) 具有过滤功能,可以人工设定StopWords列表.如果不是人工设定,系统会给出默认的StopWords列表.
(4) 使用P-stemming算法对于英文部分进行词缀处理.
Ⅶ Lucene 如何建立索
package com.onewaveinc.core.components.search;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.FilterIndexReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.RAMDirectory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Date;
import java.util.Random;
/**
* 建立索引文件的工具类,外部类根据记录生成IndexObject后可采用本类建立索引
*/
public class Indexer {
private String indexDir;//index文件放的路径
private IndexWriter writer = null;
private IndexReader reader = null;
public void setIndexDir(String indexDir) {
this.indexDir = indexDir;
}
public static void main(String[] args) {
Indexer index = new Indexer();
index.setIndexDir("D:/workspace/index");
if (index.isCreate()) {
index.start("create");
} else {
index.start("append");
}
long timestamp = System.currentTimeMillis();
Random ran = new Random(12345678);
for (int i = 0; i <= 500000; i++) {
IndexedObject obj = new IndexedObject();
obj.setKey("1234567890" + i);
Map map = new HashMap();
map.put("name", obj.getKey() + ran.nextInt());
map.put("englishname", obj.getKey() + ran.nextInt());
map.put("chinesename", obj.getKey() + ran.nextInt());
map.put("keyword", obj.getKey() + ran.nextInt());
obj.setTexts(map);
index.index(obj);
if (i % 1000 == 0 && i != 0) {
long ntimestamp = System.currentTimeMillis();
index.finish();
System.out.println("finish耗费时间" + (System.currentTimeMillis() - ntimestamp));
index.start("append");
System.out.println("到" + i + "条数据耗费时间" + (System.currentTimeMillis() - timestamp));
}
}
}
/**
* 开始覆盖/追加/删除索引
*
* @param action 要做的动作(delete/create/append)
*/
public void start(String action) {
try {
if (!"delete".equals(action.trim().toLowerCase())) {
Analyzer analyzer = new StandardAnalyzer(new String[0]);
writer = new IndexWriter(indexDir, analyzer, "create".equals(action.trim().toLowerCase()));
writer.setMergeFactor(1000);
writer.setMaxBufferedDocs(1000);
writer.setMaxMergeDocs(100000);
} else if ("delete".equals(action.trim().toLowerCase())) {//如果只是删除索引,只需要打开已有索引
reader = FilterIndexReader.open(indexDir);
}
} catch (IOException e) {
throw new IndexException(e);
}
}
/**
* 进行索引
*
* @param obj 放有要索引信息的类
*/
public void index(IndexedObject obj) {
if (writer != null) {
Document doc = new Document();
doc.add(new Field("key",obj.getKey(),Field.Store.YES,Field.Index.NO_NORMS));
for (Iterator keys = obj.getDataCache().keySet().iterator(); keys.hasNext();) {
String key = (String) keys.next();
doc.add(new Field(key,obj.getDataCache().get(key).toString(),Field.Store.YES,Field.Index.NO));//记录缓存数据,不用搜索,不做索引
}
Map keywords = obj.getKeywords();
Iterator keys = keywords.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
Object value = keywords.get(key);
Field field = null;
if (value instanceof Date && value != null)
field = new Field(key, value.toString() == null ? "" : value.toString(),Field.Store.YES,Field.Index.NO_NORMS);
else
field = new Field(key, value.toString() == null ? "" : value.toString(),Field.Store.YES,Field.Index.NO_NORMS);
doc.add(field);
}
Map texts = obj.getTexts();
keys = texts.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
doc.add(new Field(key, texts.get(key) == null ? "" : texts.get(key).toString(),Field.Store.YES,Field.Index.TOKENIZED));
}
try {
writer.addDocument(doc);
} catch (IOException e) {
throw new IndexException(e);
}
} else {
try {
reader.deleteDocuments(new Term("key", obj.getKey()));
} catch (IOException e) {
throw new IndexException(e);
}
}
}
/**
* 删除符合条件的索引
*
* @param key
* @param value
*/
public void delete(String key, String value) {
try {
reader.deleteDocuments(new Term(key, value));
} catch (IOException e) {
throw new IndexException(e);
}
}
/**
* 索引建立完成,关闭句柄,释放文件系统lock
*/
public void finish() {
try {
if (writer != null) {
writer.optimize();
writer.close();
writer = null;
} else {
reader.unlock(reader.directory());
reader.close();
reader = null;
}
} catch (IOException e) {
throw new IndexException(e);
}
}
/**
* 判断是新建索引 还是批量增加索引
* @return
*/
public boolean isCreate() {
boolean result = false;
try {
RAMDirectory indexFolder = new RAMDirectory(indexDir);
if(indexFolder.list().length < 1) {
result = true;
}
} catch (Exception e) {
result = true;
}
return result;
}
}
Ⅷ 如何使用lucene中的扩展词典
你可以使用一个开源的中文分词包MMAnalyzer,网上可以下到。在程序中引入此包。这个分词包的大概作用是:
1、支持英文、数字、中文(简体)混合分词
2、常用的数量和人名的匹配
3、超过22万词的词库整理
4、实现正向最大匹配算法
5、词典的动态扩展
6、分词效率: 第一次分词需要1-2秒(读取词典),之后速度基本与Lucene自带分词器持平。
具体方法:
Analyzer analyzer = new MMAnalyzer();
然后用这个analyzer的analyzer.tokenStream()来对某一个字符串进行分词(比如“中华人民共和国”,最终可以得出分词结果,有固定的类来表示结果,具体怎么写看其文档。
从这个例子来看,结果是“中华” “人民” “共和国”,利用某些类来迭代得出每一个词并存入Map中做key,每迭代出一个分词结果就在map中查找一下,若已有此词为key,则在value里加1。这样就实现了你的需求。
Ⅸ lucene 功能强大吗相比百度谷歌差多远
一点都不难,我们毕业设计就用lucene做的,写一个简单的搜索引擎,几百行代码就成了。占多大内存影响因素很多:1、你存储lucene索引位置(硬盘还是内存),2、你程序写的好不好,3你要索引站内文件还是这个互联网的,至于第三个问题,你自己想想看,人家网络和google是专门有公司运营的,当然比你一个人写的强大多了,在一个问题就是lucene只是一个工具包,不能和网络,google比的