- 浏览: 258525 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (289)
- java (72)
- oracle (3)
- mysql (5)
- spring (28)
- hibernate (2)
- osgi (0)
- linux (2)
- ExtJs (1)
- jvm (0)
- mybatis (7)
- 分布式 (11)
- MINA (6)
- apache+tomcat (13)
- js+htm (7)
- android (44)
- http (1)
- hbase+hdoop (0)
- memcache (13)
- search (27)
- 部署及性能 (12)
- mongoDB (2)
- 多线程 (12)
- 安全管理验证 (9)
- struts (1)
- webservice (0)
- easyUI (1)
- spring security (16)
- pattern (6)
- 算法 (2)
最新评论
-
lzh8189146:
CommonsHttpSolrServer这个类,现在是不是没 ...
CommonsHttpSolrServer -
xiaochanzi:
我按照你的方法试了下,tomcat6可以发布,但是访问任何网页 ...
基于内嵌Tomcat的应用开发 -
phoneeye:
麻烦你,如果是抄来的文章,请给出来源。谢谢
ant 两则技巧 -
neverforget:
转载不注明出处
Spring Security3.1登陆验证 替换 usernamepasswordfilter -
liang1022:
若不使用eclipse ,如何在命令行下 运行服务端程序 ?
WebService CXF学习(入门篇2):HelloWorld
如果你想快速查询你磁盘上文件,或查询邮件、Web页面,甚至查询存于数据库的数据,你都可以借助于Lucene来完成。但是要完成查询就必须先建立索引。首先从Lucene API说起:
1、 Lucene API(核心操作类)
IndexWriter | 创建和维护索引(向原索引中添加新Document,设置合并策略、优化等) |
FSDirectory | 最主要用来存储索引文件的类,表示将索引文件存储到文件系统 |
Document | 索引和查询的原子单元,一个Document包含一系列Field |
IndexReader | 一个抽象类,提供了访问索引的接口,当然访问索引也可以通过它的子类来完成 |
Analyzer | 分词类,它有一系列子类,都是用来将文本解析成TokenStream |
Searcher | 用于查询索引的核心类 |
2、创建索引
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_29),true, IndexWriter.MaxFieldLength.UNLIMITED);
- Document doc = new Document();
- doc.add(new Field("id", "101", Field.Store.YES, Field.Index.NO));
- doc.add(new Field("name", "kobe bryant", Field.Store.YES, Field.Index.NO));
- writer.addDocument(doc);
- writer.optimize();
- writer.close();
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_29),true, IndexWriter.MaxFieldLength.UNLIMITED);
- Document doc = new Document();
- doc.add(new Field("id", "101", Field.Store.YES, Field.Index.NO));
- doc.add(new Field("name", "kobe bryant", Field.Store.YES, Field.Index.NO));
- writer.addDocument(doc);
- writer.optimize();
- writer.close();
如上所示将索引文件存储于工作目录下lucene.blog文件夹 ,创建了Document,向Document里添加了两个Field id和name,然后使用IndexWriter的addDocument(Document)方法将其添加到索引目录下的索引文件中,然后使用IndexWriter的optimize()方法进行对索引文件优化,最后关闭IndexWriter;
3、通过IndexWriter删除索引中Document
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
- writer.deleteDocuments(new Term("id", "101"));
- writer.commit();
- writer.close();
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
- writer.deleteDocuments(new Term("id", "101"));
- writer.commit();
- writer.close();
如上先打开索引位置(工作目录下lucene.blog文件夹 ),然后直接调运IndexWriter的deleteDocuments(Term)方法删除上面2中创建的Document,注意必须调运commit()方法,上面2中之所以没有commit()是因为optimize()方法中存在默认Commit方法;
4、通过IndexWriter更新索引中Document
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
- Document doc = new Document();
- doc.add(new Field("id", "101", Field.Store.YES, Field.Index.ANALYZED)); // Field.Index.ANALYZED
- doc.add(new Field("name", "kylin soong", Field.Store.YES, Field.Index.ANALYZED));
- writer.updateDocument(new Term("id", "101"), doc);
- writer.commit();
- writer.close();
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
- Document doc = new Document();
- doc.add(new Field("id", "101", Field.Store.YES, Field.Index.NO));
- doc.add(new Field("name", "kylin soong", Field.Store.YES, Field.Index.NO));
- writer.updateDocument(new Term("id", "101"), doc);
- writer.commit();
- writer.close();
通过IndexWriter的updateDocument(Term, Document)来完成更新,具体是将包含Term("id", "101")的Document删除,然后将传入的Document添加到索引文件;
5、Field选项意义
- Field field = new Field(
- "101",
- "kobe bryant",
- Field.Store.YES,
- Field.Index.ANALYZED,
- Field.TermVector.YES);
- Field field = new Field(
- "101",
- "kobe bryant",
- Field.Store.YES,
- Field.Index.ANALYZED,
- Field.TermVector.YES);
如上代码显示Field各属性设置情况,下面简单说明这些属性选项的意义
Field.Store.*决定是否将Field的完全值进行存储,注意:不能将整个文本内容存储,这样导致索引文件过大
Field.Store.YES | 存储,一旦存储,你可以用完整的Field的完全值作为查询条件查询(id:101) |
Field.Store.NO | 不存储 |
Field.Index.*控制Field的值是否可查询通过索引成的索引文件
Field.Index.ANALYZED | 用Analyzer将Field的值分词成多个Token |
Field.Index.NOT_ANALYZED | 不对Field的值分词,将Field的值作为一个Token处理 |
Field.Index.ANALYZED_NO_NORMS | 类似ANALYZED,但不存常规信息到索引文件 |
Field.Index.NOT_ANALYZED_NO_NORMS | 类似NOT_ANALYZED,但不存常规信息到索引文件 |
Field.Index.NO | 不进行索引,Field的值不可被搜索 |
如果你想要检索出唯一的terms在搜索时,或对搜索结果进行加亮处理等操作是Field.TermVector.*是必要的
Field.TermVector.YES | 记录唯一的terms,当重复发生时记下重复数,在不做额外处理 |
Field.TermVector.WITH_POSITIONS | 在上面基础上记录下位置 |
Field.TermVector.WITH_OFFSETS | 在TermVector.YES基础上记录偏移量 |
Field.TermVector.WITH_POSITIONS_OFFSETS | 在TermVector.YES基础上记录偏移量和位置 |
Field.TermVector.NO | 不做任何处理 |
6、索引numbers
- Document doc = new Document();
- NumericField field1 = new NumericField("id");
- field1.setIntValue(101);
- doc.add(field1);
- NumericField field2 = new NumericField("price");
- field1.setDoubleValue(123.50);
- doc.add(field2);
- Document doc = new Document();
- NumericField field1 = new NumericField("id");
- field1.setIntValue(101);
- doc.add(field1);
- NumericField field2 = new NumericField("price");
- field1.setDoubleValue(123.50);
- doc.add(field2);
如上所示为索引numbers方法;
7、索引Date和Time
- Document doc = new Document();
- doc.add(new NumericField("timestamp").setLongValue(new Date().getTime()));
- doc.add(new NumericField("day").setIntValue((int) (new Date().getTime()/24/3600)));
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- doc.add(new NumericField("dayOfMonth").setIntValue(cal.get(Calendar.DAY_OF_MONTH)));
- Document doc = new Document();
- doc.add(new NumericField("timestamp").setLongValue(new Date().getTime()));
- doc.add(new NumericField("day").setIntValue((int) (new Date().getTime()/24/3600)));
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- doc.add(new NumericField("dayOfMonth").setIntValue(cal.get(Calendar.DAY_OF_MONTH)));
实质上对Date和Time的处理是将Date和Time转化为numbers来处理,注意:当然也可以把Date和Time以及上面的numbers当做字符串来处理,不过这样影响查询;
8、IndexWriter的其他同法
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.LIMITED);
- writer.setMaxFieldLength(1);
- MergePolicy policy = new LogByteSizeMergePolicy(writer);
- writer.setMergePolicy(policy);
- writer.optimize(5);
- writer.close();
- Directory dir = FSDirectory.open(new File("lucene.blog"));
- IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.LIMITED);
- writer.setMaxFieldLength(1);
- MergePolicy policy = new LogByteSizeMergePolicy(writer);
- writer.setMergePolicy(policy);
- writer.optimize(5);
- writer.close();
如上IndexWriter.MaxFieldLength.LIMITED设定了Field截取功能,如果Field值相当长,而你只想索引Field值的前固定个字符,可以用Field截取功能来实现;IndexWriter的setMergePolicy(policy),可以设定合并策略,另外optimize(int maxNumSegments)方法可以通过参数设定优化成的Segment个数;
9、根据确定的term查询
- IndexReader reader = IndexReader.open(FSDirectory.open(new File("lucene.blog")),true);
- IndexSearcher searcher = new IndexSearcher(reader);
- Term term = new Term("id","101");
- Query query = new TermQuery(term);
- TopDocs topDocs = searcher.search(query, 10);
- System.out.println(topDocs.totalHits);
- ScoreDoc[] docs = topDocs.scoreDocs;
- System.out.println(docs[0].doc + " " + docs[0].score);
- Document doc = searcher.doc(docs[0].doc);
- System.out.println(doc.get("id"));
- IndexReader reader = IndexReader.open(FSDirectory.open(new File("lucene.blog")),true);
- IndexSearcher searcher = new IndexSearcher(reader);
- Term term = new Term("id","101");
- Query query = new TermQuery(term);
- TopDocs topDocs = searcher.search(query, 10);
- System.out.println(topDocs.totalHits);
- ScoreDoc[] docs = topDocs.scoreDocs;
- System.out.println(docs[0].doc + " " + docs[0].score);
- Document doc = searcher.doc(docs[0].doc);
- System.out.println(doc.get("id"));
如上示例显示了一个Lucene查询的基本方法,IndexSearcher是核心的查询类,IndexReader 可以读取索引文件,IndexSearcher有一系列重载的Search()方法,可以根据传入不同参数进行不同查询处理,ScoreDoc数组保存查询结果,和相关得分;
10、根据QueryParser查询,并收集查询结果
- IndexReader reader = IndexReader.open(FSDirectory.open(new File("lucene.blog")),true);
- IndexSearcher searcher = new IndexSearcher(reader);
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
- QueryParser parser = new QueryParser(Version.LUCENE_29,"name",analyzer);
- String queryString = "kobe";
- Query query = parser.parse(queryString);
- TopScoreDocCollector collector = TopScoreDocCollector.create(10, false);
- searcher.search(query, collector);
- ScoreDoc[] hits = collector.topDocs().scoreDocs;
- for(int i = 0 ; i < hits.length ; i ++) {
- Document doc = searcher.doc(hits[i].doc);
- String name = doc.get("name");
- if (name != null) {
- System.out.println(name);
- }
- }
- IndexReader reader = IndexReader.open(FSDirectory.open(new File("lucene.blog")),true);
- IndexSearcher searcher = new IndexSearcher(reader);
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
- QueryParser parser = new QueryParser(Version.LUCENE_29,"name",analyzer);
- String queryString = "kobe";
- Query query = parser.parse(queryString);
- TopScoreDocCollector collector = TopScoreDocCollector.create(10, false);
- searcher.search(query, collector);
- ScoreDoc[] hits = collector.topDocs().scoreDocs;
- for(int i = 0 ; i < hits.length ; i ++) {
- Document doc = searcher.doc(hits[i].doc);
- String name = doc.get("name");
- if (name != null) {
- System.out.println(name);
- }
- }
如上为一个使用QueryParser查询关键字“kobe”的实例,另外还对查询结果进行了收集
11、使用Lucene图形化工具Luke来操作索引
Luke使用非常简单:
下载:http://code.google.com/p/luke/ 点击下载最新版本,下载完成直接点击下载的jar包,就可以进入图形化操作界面,选择索引的目录就可以对索引进行图形化操作
发表评论
-
提高nutch爬取效率
2012-06-08 12:47 945提高nutch爬取效率 分类 ... -
CommonsHttpSolrServer
2012-03-28 09:31 2082CommonsHttpSolrServer ... -
利用SOLR搭建企业搜索平台 之十(数据库数据导入到solr)
2012-03-28 09:31 748利用SOLR搭建企业搜索平台 之十(数据库数据导 ... -
利用SOLR搭建企业搜索平台 之九(solr的查询语法)
2012-03-28 09:31 838利用SOLR搭建企业搜索平台 之九(solr的查 ... -
利用SOLR搭建企业搜索平台 之八(solr 实现去掉重复的搜索结果,打SOLR-236_collapsing.patch补丁)
2012-03-28 09:31 983引用Bory.Chanhttp://blog.chenlb.c ... -
利用SOLR搭建企业搜索平台 之五(solrj)
2012-03-27 14:59 860利用SOLR搭建企业搜索平台 之五(solrj) ... -
Solr solrconfig.xml的翻译
2012-03-13 08:23 896Solr solrconfig.xml的翻译 ... -
使用Apache Solr对数据库建立索引
2012-03-13 08:23 863使用Apache Solr对数据库建立索引 ( ... -
解决DataImportHandler从数据库导入大量数据而内存溢出的问题
2012-03-13 08:23 933解决DataImportHandler从数据库导入大 ... -
Solr 创建索引的原理 源码分析
2012-03-13 08:24 1163Solr 创建索引的原理 源码分析 (2011 ... -
Solr Replication (复制) 索引和文件的工作机制
2012-03-13 08:24 812Solr Replication (复制) 索引和文 ... -
Solr 查询中fq参数的解析原理
2012-03-14 08:13 820Solr 查询中fq参数的解析原理 (2011- ... -
Solr 分词器(analyzer)是怎么传到Luence的
2012-03-14 08:13 1092Solr 分词器(analyzer)是怎么传到Lue ... -
SOLR的分布式部署
2012-03-14 08:14 1033转载:http://blog.sina.com.cn/s/bl ... -
Solr 删除数据的几种方式
2012-02-22 08:40 1007转载:Solr 删除数据的几种方式 发表于:2010 ... -
Solr Data Import 快速入门
2012-02-26 12:12 829转载:Solr Data Import 快速入门 发 ... -
使用 solr php 的输出
2012-02-22 08:41 852转载:使用 solr php 的输出 发表于:200 ... -
Solr Multicore 结合 Solr Distributed Searching 切分大索引来搜索
2012-02-26 12:13 791Solr Multicore 结合 Solr Dist ... -
Solr Multicore 试用小记
2012-02-26 12:13 753Solr Multicore 试用小记 转载: ... -
Solr1.4.0源码分析二 Solr分布式搜索中URL的正确用法和原理
2012-02-26 12:13 987Solr1.4.0源码分析二 Solr分布式搜索 ...
相关推荐
《Lucene使用代码实例之搜索文档》 Lucene是一个高性能、全文检索库,它提供了强大的文本分析和索引功能,广泛应用于搜索引擎开发和其他需要高效文本处理的场景。本篇文章主要面向初学者,通过实例详细解释如何使用...
### Lucene 使用正则表达式 #### 知识点概览 1. **Lucene简介** 2. **正则表达式(regex)在Lucene中的应用** 3. **regexQuery详解** 4. **示例代码解析** 5. **索引创建与查询流程** 6. **正则表达式的语法** #### ...
lucene使用总结笔记lucene使用总结笔记lucene使用总结笔记lucene使用总结笔记lucene使用总结笔记
在使用 Lucene 之前,首先需要将其添加到项目依赖中。如果你使用的是 Maven,可以在 pom.xml 文件中添加对应的 Lucene 依赖。对于其他构建工具,如 Gradle 或 Ivy,也有相应的配置方式。确保选择与项目所用 Java ...
**Lucene 概述** Lucene 是一个高性能、全文本搜索库,由 ...在提供的源代码中,可能包含了如何使用 Lucene 进行索引创建、查询以及结果处理的示例,通过对这些代码的分析和学习,能够进一步掌握 Lucene 的使用技巧。
下面是一个简单的Lucene使用示例,演示如何创建索引和添加文档: ```java // 创建索引写入器 IndexWriter writer = new IndexWriter("/data/index/", new StandardAnalyzer(), true); // 创建文档 Document doc = ...
### Lucene 使用教程 #### 一、Lucene简介 Lucene是一个高性能、全功能的文本搜索引擎库,由Java编写而成,被广泛应用于各种基于文本的数据检索场景中。无论是用于网站内容搜索还是文档管理系统的全文搜索功能,...
1. **文档分析**:Lucene使用分析器将原始输入转换为可索引的术语。分析器可以定制以适应不同的语言和领域需求。 2. **字段和类型**:每个文档由多个字段组成,如标题、正文、作者等。每个字段可以指定其类型,如...
在使用2012版时异常:ClassNotFoundException: org.apache.lucene.analysis.tokenattributes.CharTermAttribute 庖丁分词 使用 paoding-analysis-2.0.4-beta.zip 版时异常 Exception in thread "main" java.lang....
博文链接中提到的是一个关于Lucene3的博客文章,可能详细介绍了如何在实际项目中使用Lucene进行全文检索。博主"chinaxxren"在ITEYE上分享了这篇博客,虽然具体内容未在描述中给出,但我们可以推测博主可能讲解了以下...
- **评分和排序**:Lucene使用TF-IDF算法计算文档与查询的相关性,用于确定搜索结果的排序。 - **更新和删除**:使用IndexWriter可以更新已有文档,或通过ID删除文档。 - **多线程索引**:通过控制IndexWriter的...
默认情况下,Lucene使用TF-IDF相似度计算查询与文档的相关性。TF-IDF是“词频-逆文档频率”的缩写,它重视在少有文档中出现的词项,认为这样的词项更能区分文档。然而,TF-IDF并未考虑文档长度,可能会导致短文档被...
- 使用处理后的关键词搜索索引,找到对应的Document。 - 用户从找到的Document中提取所需信息。 【核心概念】 1. **Analyzer**: Analyzer是处理字符串的关键组件,它按照特定规则将字符串拆分成有意义的词语,...
3. **倒排索引**:Lucene使用倒排索引技术,通过构建索引表,使得搜索效率大大提高。 4. **多字段搜索**:允许用户对文档的不同字段进行独立或组合的搜索。 5. **模糊搜索**:支持通配符、短语、近似和模糊搜索,...
1. **分词与索引**:Lucene使用高效的分词器将文档内容分解成独立的词汇项(tokens),然后建立倒排索引。倒排索引是一种数据结构,它将每个词汇项映射到包含该词汇项的文档列表,极大地加速了搜索过程。 2. **搜索...
查询执行阶段,Lucene使用QueryParser解析用户的查询字符串,生成对应的Query对象。然后,Searcher对象利用这些查询对象在索引中寻找匹配的文档。这一过程涉及到Scorer和Collector,Scorer计算每个文档的相关性分数...
3. **评分(Scoring)**:Lucene使用TF-IDF算法来评估文档与查询的相关性,给出一个评分。评分高的文档在搜索结果中优先显示。 4. **结果集(Hit)**:搜索返回一个`TopDocs`对象,包含匹配文档的总数和最高评分的...
最后,IKAnalyzer.cfg.xml是IK分词器的配置文件,用于设置分词器的行为,如是否开启全模式、是否使用自定义词典等。通过修改这个配置文件,我们可以对分词过程进行精细化控制。 总的来说,"lucene6.6+拼音分词+ik...