全文检索之lucene的使用(上)
来源:互联网 发布:c语言生成随机数 编辑:程序博客网 时间:2024/05/16 10:24
全文检索技术适合做各种网站的站内搜索,例如京东,淘宝等电商网站,是一门非常使用的技术,这里讲解其原生技术lucene的使用,在全文检索之lucene的使用(下)讲讲解框架solr的使用,lucene的jar下载地址:http://lucene.apache.org/
以下为代码实现:
package com.ilike.lucene;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
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.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
/**
* 全文检索引擎lucene的使用 ①导入相应的jar包及配置文件包括如下 :
* commons-io-2.4.jar
* IKAnalyzer2012FF_u1.jar
* lucene-analyzers-common-4.10.3.jar
* lucene-analyzers-smartcn-4.10.3.jar
* lucene-core-4.10.3.jar
* lucene-queryparser-4.10.3.jar
*
* IKAnalyzer.cfg.xml
* ext.dic(需要识别的新词)
* stopword.dic(不需要创建索引的词)
*
* @author 桑伟东
*
*/
public class LuceneDemo1 {
/* * 1.创建索引 */@Testpublic void testCreateIndex1() throws Exception { // 1.1 创建一个indexWriter对象 Directory directory = FSDirectory.open(new File("D:\\tmp\\lucene_indexRes")); // Analyzer analyzer=new // StandardAnalyzer();//该分析器是apache官方推介使用,但是只适合分析英文 Analyzer analyzer = new IKAnalyzer();// 这是一个较为强大的中文分析器 IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LATEST, analyzer); IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); // 1.2创建field对象,将field添加到document对象中 // 加载你要创建索引的文件 File file = new File("D:\\tmp\\lucene_temp_src"); File[] files = file.listFiles(); for (File file2 : files) { // 1.3创建document对象 Document document = new Document(); // 1.3.1文件名称 String file_name = file2.getName(); Field fileNameField = new TextField("fileName", file_name, Store.YES);// YES表示存储在索引库中,反之则不存 // 1.3.2文件大小 Long file_size = FileUtils.sizeOf(file2); Field fileSizeField = new LongField("fileSize", file_size, Store.YES); // 1.3.3文件路径 String file_path = file2.getPath(); Field filePathField = new StoredField("filePath", file_path); // 1.3.4文件内容 String file_content = FileUtils.readFileToString(file2); Field fileContentField = new TextField("fileContent", file_content, Store.NO); // 1.3.5将域对象添加到document中 document.add(fileNameField); document.add(fileSizeField); document.add(filePathField); document.add(fileContentField); // 1.4使用indexWriter对象将document对象写入文档库 indexWriter.addDocument(document); } // 1.5关闭indexWriter对象 indexWriter.close();}/* * 2.搜索索引 */@Testpublic void testSearchIndex1() throws Exception { // 2.1创建Directory对象,也就是索引库的位置 Directory directory = FSDirectory.open(new File("D:\\tmp\\lucene_indexRes")); // 2.2创建indexReader对象,需要制定Directory IndexReader indexReader = DirectoryReader.open(directory); // 2.3创建indexSearch对象,需要制定IndexReader IndexSearcher indexSearcher = new IndexSearcher(indexReader); // 2.4创建一个TearmQuery对象,指定查询的域和查询的关键词 Query query = new TermQuery(new Term("fileN", "文件名")); // 2.5执行查询 TopDocs topDocs = indexSearcher.search(query, 10); // 2.6返回查询结果,遍历查询结果并输出 ScoreDoc[] scoreDocs = topDocs.scoreDocs; for (ScoreDoc scoreDoc : scoreDocs) { int docId = scoreDoc.doc; Document document = indexSearcher.doc(docId); // 文件名称 String file_name = document.get("fileName"); System.out.println(file_name); // 文件内容 String file_content = document.get("fileContent"); System.out.println(file_content); // 文件大小 String file_size = document.get("fileSize"); System.out.println(file_size); // 文件路径 String file_path = document.get("filePath"); System.out.println(file_path); System.out.println("---------------------"); } // 2.7关闭indexReader对象 indexReader.close();}/** * 可以挑选不同的分析器查看不同的分词效果,IKAnalyzer分词器目前最适合分析中文 如果有新词出现,可添加到配置文件ext.dic中 * * @throws Exception */@Testpublic void testTokenStream() throws Exception { // 创建一个标准分析器对象 // Analyzer analyzer = new StandardAnalyzer(); // Analyzer analyzer = new CJKAnalyzer(); // Analyzer analyzer = new SmartChineseAnalyzer(); Analyzer analyzer = new IKAnalyzer(); // 获得tokenStream对象 // 第一个参数:域名,可以随便给一个 // 第二个参数:要分析的文本内容 // TokenStream tokenStream = analyzer.tokenStream("test", // "The Spring Framework provides a comprehensive programming and // configuration model."); TokenStream tokenStream = analyzer.tokenStream("test", "高富帅可以用二维表结构来逻辑表达实现的数据"); // 添加一个引用,可以获得每个关键词 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); // 添加一个偏移量的引用,记录了关键词的开始位置以及结束位置 OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); // 将指针调整到列表的头部 tokenStream.reset(); // 遍历关键词列表,通过incrementToken方法判断列表是否结束 while (tokenStream.incrementToken()) { // 关键词的起始位置 System.out.println("start->" + offsetAttribute.startOffset()); // 取关键词 System.out.println(charTermAttribute); // 结束位置 System.out.println("end->" + offsetAttribute.endOffset()); } tokenStream.close();}
}
package com.ilike.lucene;
import java.io.File;
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.Store;
import org.apache.lucene.document.TextField;
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.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
/**
* 索引管理(增加,修改,删除,查询)
* 增加:入门程序类LuceneDemo1已写过
* 修改:
* 删除:
* 查询:入门程序类LuceneDemo1已写过精准查询
* 查询方式:①子类查询:只需要按照查询需求,挑选Query的子类即可
* ②解析查询:需要写语法,可打印子类查询中的query对象,了解语法
* @author 桑伟东
*
*
*/
public class LuceneManager {
/*1.删除全部索引 * */@Testpublic void testDeleteAll() throws Exception { // 1.1获取indexWriter对象 IndexWriter indexWriter=getIndexWriter(); // 1.2调用方法删除所有索引 indexWriter.deleteAll(); // 1.3关闭流 indexWriter.close();}/** * 2.根据条件删除指定索引 * @throws Exception */@Testpublic void testDeleteByCondition() throws Exception { // 2.1获取indexWriter对象 IndexWriter indexWriter=getIndexWriter(); // 2.2创建查询条件(fileName中名字中带有apache的索引) Query query=new TermQuery(new Term("fileName", "apache")); // 2.3调用方法删除指定索引 indexWriter.deleteDocuments(query); // 2.4关闭流 indexWriter.close();}/** * 3.修改索引的方法 * @throws Exception */@Testpublic void testUpdateByCondition() throws Exception { // 3.1获取indexWriter对象 IndexWriter indexWriter=getIndexWriter(); // 3.2创建要新增的索引 Document document=new Document(); document.add(new TextField("fileN", "测试文件名1", Store.YES)); document.add(new TextField("fileC", "测试文件1的内容", Store.YES)); // 3.3调用方法修改指定的索引(第一个参数中的内容会被删除,第二个参数是要新增的内容,第三个参数是中文词法分析器对象) indexWriter.updateDocument(new Term("fileName", "apache"), document, new IKAnalyzer()); // 3.4关闭流 indexWriter.close();}/** * 4.查询所有 * @throws Exception */@Testpublic void testQueryAll() throws Exception { // 4.1获取IndexSearcher对象 IndexSearcher indexSearcher=getIndexSearcher(); // 4.2创建一个MatchAllDocsQuery对象 Query query=new MatchAllDocsQuery(); // 4.3执行查询并打印查询结果 printQueryResult( query, indexSearcher); // 4.4关闭资源 indexSearcher.getIndexReader().close();}/** * 5.根据数值范围查询 * @throws Exception */@Testpublic void testQueryByCondition() throws Exception { // 5.1获取IndexSearcher对象 IndexSearcher indexSearcher=getIndexSearcher(); // 5.2创建一个NumericRangeQuery对象,("fileSize"表示域, //20l表示最小值,1000l表示最大值,false表示不包含20,true表示包含1000 Query query=NumericRangeQuery.newLongRange("fileSize", 20l, 1000l, false, true); // 5.3执行查询并打印查询结果 printQueryResult( query, indexSearcher); // 5.4关闭资源 indexSearcher.getIndexReader().close();}/** * 6.多条件组合查询 * @throws Exception */@Testpublic void testQueryByConditions() throws Exception { // 5.1获取IndexSearcher对象 IndexSearcher indexSearcher=getIndexSearcher(); // 5.2创建组合查询的条件 BooleanQuery booleanQuery=new BooleanQuery(); Query query1=new TermQuery(new Term("fileName", "java")); Query query2=NumericRangeQuery.newLongRange("fileSize", 10l, 100000l, false, true); // 5.3执行查询并打印查询结果(MUST表示条件必须满足,MUST_NOT表示不满足,SHOULD表示可以没有) booleanQuery.add(query1, Occur.MUST); booleanQuery.add(query2, Occur.MUST); printQueryResult( booleanQuery, indexSearcher); // 5.4关闭资源 indexSearcher.getIndexReader().close();}/** * 1.条件解析的对象查询 * @throws Exception */@Testpublic void testParserQuery() throws Exception { // 1.1获取IndexSearcher对象 IndexSearcher indexSearcher=getIndexSearcher(); // 1.2创建查询的条件,默认查询的域是fileName QueryParser queryParser=new QueryParser("fileName", new IKAnalyzer()); //Query query=queryParser.parse("*:*");// *:*代表 域:值,写法可以参照上文的查询,打印上文查询中的query对象就可知道 Query query=queryParser.parse("apache");//表示查询默认fileName域的apache printQueryResult( query, indexSearcher); // 1.4关闭资源 indexSearcher.getIndexReader().close();}/** * 2.条件解析的对象查询(多个默认查询域) * @throws Exception */@Testpublic void testParserQuery2() throws Exception { // 1.1获取IndexSearcher对象 IndexSearcher indexSearcher=getIndexSearcher(); // 1.2创建查询的条件,默认查询的域是fileName和fileContent String [] fields={"fileName","fileContent"}; MultiFieldQueryParser multiFieldQueryParser=new MultiFieldQueryParser(fields, new IKAnalyzer()); //Query query=queryParser.parse("*:*");// *:*代表 域:值 Query query=multiFieldQueryParser.parse("apache is java");//表示查询默认fileName域的apache printQueryResult( query, indexSearcher); // 1.4关闭资源 indexSearcher.getIndexReader().close();}/** * 抽取获得IndexWriter的方法 * @return * @throws Exception */private IndexWriter getIndexWriter() throws Exception { // 1.1 创建一个indexWriter对象 Directory directory =FSDirectory.open(new File("D:\\tmp\\lucene_indexRes")); Analyzer analyzer=new StandardAnalyzer(); IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LATEST, analyzer); return new IndexWriter(directory, indexWriterConfig);}/** * 抽取获得IndexSearcher的方法 * @return * @throws Exception */private IndexSearcher getIndexSearcher() throws Exception { // 2.1创建Directory对象,也就是索引库的位置 Directory directory =FSDirectory.open(new File("D:\\tmp\\lucene_indexRes")); // 2.2创建indexReader对象,需要制定Directory IndexReader indexReader=DirectoryReader.open(directory); // 2.3创建indexSearch对象,需要制定IndexReader return new IndexSearcher(indexReader);}private void printQueryResult(Query query,IndexSearcher indexSearcher) throws Exception { // 2.5执行查询 TopDocs topDocs =indexSearcher.search(query, 10); // 2.6返回查询结果,遍历查询结果并输出 ScoreDoc [] scoreDocs= topDocs.scoreDocs; for (ScoreDoc scoreDoc : scoreDocs) { int docId=scoreDoc.doc; Document document=indexSearcher.doc(docId); //文件名称 String file_name1=document.get("fileName"); System.out.println(file_name1); //文件内容 String file_content1=document.get("fileC"); System.out.println(file_content1); //文件大小 String file_size=document.get("fileSize"); System.out.println(file_size); //文件路径 String file_path=document.get("filePath"); System.out.println(file_path); System.out.println("---------------------"); }}
}
配置文件内容如下:
- 全文检索之lucene的使用(上)
- 全文检索Lucene的使用
- 全文检索引擎lucene的研究和使用(一)
- 全文检索引擎lucene的研究和使用(二)
- 全文检索引擎lucene的研究和使用(案例)
- 全文检索技术与Lucene的使用
- 使用lucene实现简单的全文检索
- 全文检索(lucene)
- 全文检索的基本原理(Lucene)
- Lucene全文检索之HelloWorld
- lucene 之 全文检索概述
- 全文检索之lucene入门
- 使用lucene实现全文检索
- 全文检索Lucene入门之lucene简介
- Lucene全文检索学习笔记(一):lucene的应用
- Lucene:全文检索的基本原理
- Lucene全文检索的基本原理
- 基于lucene的全文检索
- Sql 两个数据库复制数据表到另一个数据
- 单链表作业
- 04 MPI消息
- TabLayout 和 ViewPager 组合显示Fragment
- #C语言#关于求素数的思路(一般筛法到线性筛)
- 全文检索之lucene的使用(上)
- C++与Opengl交互 Python与Opnegl交互(使用鼠标函数)
- HDU4085-Peach Blossom Spring
- 删除linux自带VIM 重新安装
- 数据结构回顾与总结 图(3)Floyd算法(多源最短路问题)
- Hdu 4436 str2int 后缀自动机
- 顺序表子函数
- 加密器
- 没有指定返回类型,可能查询不到返回结果