- 浏览: 46050 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
ql0722:
没发现 其实读取的文件有中文的时候有乱码吗?
lucene 3.3 简单例子 -
accommands:
楼主有实现的代码吗?谢谢
jbpm4.4实现会签 -
中华国锋:
问下。楼主知道怎么用for-each 实现动态子流程不?
jbpm4.4实现会签 -
lizhongyi188:
请问用过lucene3.3写过自定分析器没有?
lucene 3.3 简单例子
lucene 3.3 简单例子
要看lucene的一些基本概念,看:http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/
这里主要写一个lucene3.3的简单例子:
首先,当然是helloworld程序:
其中用到了2个util类:
对搜索结果封装的类:
helloworld程序到此结束。
下面是测试中文分词器和英文分词器的简单例子:
下面是测试几种常用query的例子:
这里主要写一个lucene3.3的简单例子:
首先,当然是helloworld程序:
package com.lucene.demo; import java.io.File; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.junit.Test; import com.lucene.model.SerachResult; import com.lucene.utils.FileToDocument; import com.lucene.utils.SerachUtil; public class HelloWorld { File indexPath=new File("F:\\java\\Workspaces\\Lucene\\luceneIndex");//存放索引文件目录 Analyzer analyzer=new SmartChineseAnalyzer(Version.LUCENE_33); IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_33, analyzer); Document doc=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\IndexWriter.txt")); Document doc1=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\china.txt")); Document doc2=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\开玩笑.txt")); /** * 创建索引 */ @Test public void createIndex() throws Exception{ conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);//总是重新创建 Directory fsDir =FSDirectory.open(indexPath); long startTime =System.currentTimeMillis(); IndexWriter indexWriter =new IndexWriter(fsDir, conf); indexWriter.addDocument(doc); indexWriter.addDocument(doc1); indexWriter.addDocument(doc2); indexWriter.optimize(); indexWriter.close(); long endTime=System.currentTimeMillis(); System.out.println("共有"+indexWriter.numDocs()+"条索引"); System.out.println("建立索引用时: " + (endTime-startTime)+"毫秒"); } /** * 搜索 */ @Test public void serach() throws Exception { //1 把要搜素的文本解析为QUery String queryString ="开玩笑"; String [] fields = {"name","content"}; QueryParser queryParser =new MultiFieldQueryParser(Version.LUCENE_33, fields, analyzer); Query query =queryParser.parse(queryString); Directory fsDir =FSDirectory.open(indexPath); IndexSearcher indexSearcher= new IndexSearcher(fsDir); SerachResult serachResult=SerachUtil.serach(1, 3, query,analyzer,indexSearcher,null); System.out.println("总共有[ "+serachResult.getTotalCount()+" ]条匹配结果"); //3 打印结果 for (Document doc : (List<Document>)serachResult.getRecords()) { System.out.println(); FileToDocument.printDocumentInfo(doc); } indexSearcher.close(); } }
其中用到了2个util类:
package com.lucene.utils; import java.util.ArrayList; import java.util.List; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.InputStreamReader; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.util.NumericUtils; public class FileToDocument { /** * 将文件转换成document * @param file * @return */ public static Document file2Document(File file) { Document doc= new Document(); doc.add(new Field("name",file.getName(),Store.YES,Index.ANALYZED)); doc.add(new Field("content",readFile(file),Store.YES,Index.ANALYZED)); doc.add(new Field("size",NumericUtils.longToPrefixCoded(file.length()),Store.YES,Index.NOT_ANALYZED)); doc.add(new Field("path",file.getAbsolutePath(),Store.YES,Index.ANALYZED)); return doc; } /** * 读取文件内容 * @param file * @return */ private static String readFile(File file) { StringBuffer content =new StringBuffer(); try { BufferedReader reader =new BufferedReader(new InputStreamReader(new FileInputStream(file))); for(String line =null;(line=reader.readLine())!=null;) { content.append(line).append("\n"); } } catch (Exception e) { e.printStackTrace(); } return content.toString(); } /** * 打印document * 获取name熟悉的值的两种方法 * 1 FIeld f=doc.getField("name"); * f.StringValue(); * 2 doc.get("name"); * @param doc */ public static void printDocumentInfo(Document doc) { System.out.println("name = "+doc.get("name")); System.out.println("content = "+doc.get("content")); System.out.println("size = "+NumericUtils.prefixCodedToLong(doc.get("size"))); System.out.println("path = "+doc.get("path")); System.out.println("comment = "+doc.get("comment")); } /** * 得到该目录下得所有文件(非目录,可读,非一次,存在) * @param sourceDir * @return */ public List<File> index(File sourceDir) { File[] files=sourceDir.listFiles(); List<File> fileList= new ArrayList<File>(); for (int i = 0; i < files.length; i++) { File f=files[i]; if(!f.isDirectory() && f.canRead() && !f.isHidden() && f.exists()){ fileList.add(f); } } return fileList; } /** * 只接受txt文件的拦截器 * @author Administrator * */ private static class MyFileFilter implements FileFilter{ @Override public boolean accept(File pathname) { return pathname.getName().toLowerCase().endsWith(".txt"); } } }
package com.lucene.utils; import java.util.ArrayList; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Filter; 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.search.highlight.Formatter; import org.apache.lucene.search.highlight.Fragmenter; import org.apache.lucene.search.highlight.Highlighter; import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.Scorer; import org.apache.lucene.search.highlight.SimpleFragmenter; import org.apache.lucene.search.highlight.SimpleHTMLFormatter; import org.apache.lucene.util.Version; import com.lucene.model.SerachResult; /** * * @author: agoni * @date: Aug 13, 2011 * @function: * */ public class SerachUtil { public static SerachResult serach(int pageNo,int pageSize ,Query query,Analyzer analyzer,IndexSearcher indexSearcher,Filter filter) throws Exception { SerachResult serachResult = new SerachResult(); long startTime =System.currentTimeMillis(); //2 进行查询,并进行过滤 TopDocs topDocs=indexSearcher.search(query, filter, 10000); //准备高亮器 Formatter formatter = new SimpleHTMLFormatter("<font color='red'>","</font>"); Scorer scorer = new QueryScorer(query); Highlighter highlighter = new Highlighter(formatter, scorer); Fragmenter fragmenter = new SimpleFragmenter(100);//摘要信息的长度 highlighter.setTextFragmenter(fragmenter); //分页读取数据 List<Document> recordList =new ArrayList<Document>(); int end=Math.min(pageNo*pageSize,topDocs.totalHits); for(int i=(pageNo-1)*pageSize;i<end;i++) { ScoreDoc scoreDoc = topDocs.scoreDocs[i];//读取第几条记录 int docSn=scoreDoc.doc; //文档内部编号 Document document=indexSearcher.doc(docSn); //高亮 //当正文中没有出现关键字, 返回null String hc=highlighter.getBestFragment(analyzer, "content",document.get("content")); if(hc==null) { String content =document.get("content"); int endIndex=Math.min(100, content.length()); hc=content.substring(0,endIndex); } Field contentField=(Field) document.getFieldable("content"); contentField.setValue(hc); document.add(new Field("comment",hc,Store.YES,Index.ANALYZED));//将搜索的提示信息放入文档中 recordList.add(document); } serachResult.setPageNo(pageNo); serachResult.setPageSize(pageSize); serachResult.setTotalCount(topDocs.totalHits); serachResult.setRecords(recordList); long endTime=System.currentTimeMillis(); serachResult.setTime(endTime-startTime); return serachResult; } }
对搜索结果封装的类:
package com.lucene.model; import java.util.List; import org.apache.lucene.document.Document; /** * * @author: agoni * @date: Aug 13, 2011 * @function: * */ public class SerachResult { private int totalCount; //搜索的总记录数 private List<Document> records; //返回当前页的结果 private long Time; //搜索用时 private int pageNo; //当前页 private int pageSize; //每页数量 public SerachResult() { } /** * @param totalCount * @param recordList * @param time */ public SerachResult(int totalCount, List<Document> recordList, long time) { super(); this.totalCount = totalCount; this.setRecords(recordList); Time = time; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public long getTime() { return Time; } public void setTime(long time) { Time = time; } public int getPageNo() { return pageNo; } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public void setRecords(List<Document> records) { this.records = records; } public List<Document> getRecords() { return records; } }
helloworld程序到此结束。
下面是测试中文分词器和英文分词器的简单例子:
package com.lucene.demo; import java.io.IOException; import java.io.StringReader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.analysis.en.EnglishAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.TypeAttribute; import org.apache.lucene.util.Version; import org.junit.Test; /** * * @author: agoni * @date: Aug 14, 2011 * @function: * */ public class TestAnalyze { private String enText= "IndexWriter addDocument's a javadoc.txt menu_down up-down"; private String chText="衣服 矿泉水和分词器-看不起一个人的审美"; Analyzer enAnalyzer = new EnglishAnalyzer(Version.LUCENE_33); Analyzer chAnalyzer = new SmartChineseAnalyzer(Version.LUCENE_33); @Test public void testAnalyze() throws IOException { analyze(enAnalyzer, enText); System.out.println("---------------------------------------------------------------------------------------------------"); analyze(enAnalyzer, chText); System.out.println("---------------------------------------------------------------------------------------------------"); analyze(chAnalyzer, enText); System.out.println("---------------------------------------------------------------------------------------------------"); analyze(chAnalyzer, chText); } /** * * @param analyzer * @param text * @throws IOException */ public void analyze(Analyzer analyzer ,String text) throws IOException { System.out.println("-----------分词器:"+analyzer.getClass().getName()+"------------"); System.out.println("输入:"+text); TokenStream tokenStream = analyzer.tokenStream("content",new StringReader(text)); displayTokenStream(tokenStream); } private static void displayTokenStream(TokenStream ts) throws IOException { CharTermAttribute termAtt = (CharTermAttribute)ts.getAttribute(CharTermAttribute.class); TypeAttribute typeAtt = (TypeAttribute)ts.getAttribute(TypeAttribute.class); while (ts.incrementToken()) { System.out.println("type="+typeAtt.type()+ " "+termAtt); } System.out.println(' '); } }
下面是测试几种常用query的例子:
package com.lucene.demo; import java.io.File; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.Version; import org.junit.Test; import org.apache.lucene.search.FuzzyLikeThisQuery; import com.lucene.model.SerachResult; import com.lucene.utils.FileToDocument; import com.lucene.utils.SerachUtil; /** * * @author: agoni * @date: Aug 14, 2011 * @function: * */ public class TestQuery { File indexPath=new File("F:\\java\\Workspaces\\Lucene\\luceneIndex");//存放索引文件目录 Analyzer analyzer=new SmartChineseAnalyzer(Version.LUCENE_33); IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_33, analyzer); Document doc=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\IndexWriter.txt")); Document doc1=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\china.txt")); Document doc2=FileToDocument.file2Document(new File("F:\\java\\Workspaces\\Lucene\\datasooruce\\开玩笑.txt")); /** * 搜索 */ public void serach(Query query) { Directory fsDir; try { fsDir = FSDirectory.open(indexPath); IndexSearcher indexSearcher= new IndexSearcher(fsDir); SerachResult serachResult=SerachUtil.serach(1, 10, query,analyzer,indexSearcher,null); System.out.println("总共有[ "+serachResult.getTotalCount()+" ]条匹配结果"); //3 打印结果 for (Document doc : (List<Document>)serachResult.getRecords()) { System.out.println("--------------------------------------------------------------------------------------------------------------------------------------"); FileToDocument.printDocumentInfo(doc);//打印文档 } indexSearcher.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 关键字查询 */ @Test public void testTermQuery() { //Term term = new Term("name","开玩笑"); Term term = new Term("content","缓存"); Query query = new TermQuery(term); serach(query); } /** * 范围查询 * 参数3.4 是否包含上下边界 */ @Test public void testTermRangeQuery() { TermRangeQuery query =new TermRangeQuery("size",NumericUtils.longToPrefixCoded(100),NumericUtils.longToPrefixCoded(1000) , true, true); serach(query);//查询文件大小为100到1000之间的数据 } /** * 模糊查询 * ?表示一位 * 表示多位 */ @Test public void testWildcardQuery() { //Term term = new Term("name","index*"); //Index* 将查询不到任何结果,因为建立索引已将所有大写转为小写 //Term term = new Term("name","?ndex*"); //Term term = new Term("name","*dex*"); Term term = new Term("name","*玩?"); Query query = new WildcardQuery(term); serach(query); } /** * 短语查询 */ @Test public void testPhraseQuery() { PhraseQuery phraseQuery = new PhraseQuery(); //phraseQuery.add(new Term("content","优化"),1); //phraseQuery.add(new Term("content","缓存"),3); phraseQuery.add(new Term("content","优化")); phraseQuery.add(new Term("content","缓存")); phraseQuery.setSlop(10);//表示分词之后 两个词的相隔的次数上限 serach(phraseQuery); } /** * 最常使用的就是booleanquery了,可以将各种条件组合一起形成复杂查询 **/ @Test public void testBooleanQuery() { //条件一 PhraseQuery phraseQuery = new PhraseQuery(); phraseQuery.add(new Term("content","小弟")); phraseQuery.add(new Term("content","分词")); phraseQuery.setSlop(100);//两词组间隔最大距离 //条件二 TermRangeQuery query =new TermRangeQuery("size",NumericUtils.longToPrefixCoded(100),NumericUtils.longToPrefixCoded(500) , true, true); BooleanQuery booleanQuery = new BooleanQuery(); booleanQuery.add(phraseQuery, Occur.MUST); booleanQuery.add(query,Occur.MUST); serach(booleanQuery); } }
相关推荐
《Lucene 3.3基础功能与IK分词器3.2.8使用详解》 Apache Lucene是一款高性能、全文本检索库,被广泛应用于各种搜索引擎的开发中。本文将重点探讨Lucene 3.3版本的基础功能及其与IK分词器3.2.8的集成使用方法。 一...
接下来,创建一个简单的Lucene实例。首先,你需要定义一个`Document`对象来存储你要索引的数据,这可以包括文本、数字或日期等字段。例如: ```java Document doc = new Document(); doc.add(new TextField("title...
例如,可以创建一个QueryParser类,处理用户输入的关键词,进行分词、分析和逻辑组合,生成相应的Query实例。 #### 2.3 搜索服务 封装搜索服务是为了提供统一的搜索接口,可以包括分页搜索、高亮显示、排序等功能...
4.2 案例分析:分享基于Lucene 5.4.0的搜索引擎构建实例,例如新闻网站的全文搜索、电商产品的推荐系统等。 五、未来发展趋势 5.1 版本迭代:探讨Lucene后续版本的新特性,如6.x、7.x引入的创新技术。 5.2 社区...
下面是一个简单的Lucene使用示例,演示如何创建索引和添加文档: ```java // 创建索引写入器 IndexWriter writer = new IndexWriter("/data/index/", new StandardAnalyzer(), true); // 创建文档 Document doc = ...
- **第 2 章:快速上手**:通过一个简单的例子来演示如何使用 Lucene 创建索引并执行搜索。 - **第 3 章:理解文档和字段**:详细解释文档和字段的概念,以及如何在实际应用中合理设计文档结构。 ##### 3.2 第二...
开发者只需创建Analyzer、Document和IndexWriter实例,即可开始构建索引。 4.2 社区与生态 Lucene社区活跃,不断有新的改进和扩展,如Solr和Elasticsearch,它们基于Lucene提供更高级的服务,如分布式搜索、集群...
简单来说,Lucene提供了必要的功能和API来实现全文搜索能力,开发者可以根据需求定制开发自己的搜索应用。 - **1.2 Lucene能做什么** Lucene的核心功能非常单一,即提供基于关键字的全文搜索服务。这意味着它可以...
通过设置断点,观察类的实例化过程,跟踪方法调用,可以深入了解Lucene的实现细节。 总结,Lucene 7.4.0作为一款强大的全文搜索引擎库,其在Java开发环境中提供了高效、灵活的搜索解决方案。通过IDEA工程的集成,...
它通过集成 Apache Lucene(一个高性能、全功能的文本搜索引擎库),为开发人员提供了一种简单而强大的方式来添加搜索功能到基于 Hibernate 的应用程序中。 #### 二、开始使用 ##### 2.1 系统要求 - **Java 版本*...
1.1 Solr的起源与发展:Solr最初由Yonik Seeley创建,后来成为Apache Lucene项目的一部分,发展至今已成为全球范围内广泛使用的搜索平台。 1.2 Solr的主要功能:Solr不仅提供全文索引,还支持多种数据类型(如日期、...
3.2 一个简单的例子 包括Solr Schema设计、构建索引和搜索测试。 3.3 搜索引擎的规划设计 3.3.1 定义业务模型 3.3.2 定制索引服务 3.3.3 定制搜索服务 3.4 搜索引擎配置 3.5 如何进行索引操作? 3.5.1 基本索引...
**3.3 实例总结** - 对上述操作进行回顾,总结经验教训。 **3.4 创建JSP模版** - **创建模块**:定义网站布局的基础元素。 - **创建一个简单的模版**:使用JSP语法构建页面结构。 **3.5 如何集成JAVABEAN** - 在...