|
由于各种原因大概很长时间都要折腾solr了,既来之则安之,花了好多精力折腾的项目怎么能不好好整理学习一下,深入理解一下solr的原理。目前接触到的搜索相关的几乎就是solr和elasticsearch平分天下,而这两者由都是基于luncene开发的全文检索系统,elasticsearch暂时还没有接触,暂时被solr虐的死去活来。
什么是luncene? Luncene是java开发的信息检索类库,专注于文本的搜索和索引,对文本中提取出来的数据进行索引和检索,也就是说luncene提供了全文检索的两个核心功能,索引和检索,而其他的则需要用户自己实现,如solr和elasticsearch就是各自基于luncene的实现。
Luncene的索引是什么? Lunecen的索引本质上是一种倒排索引,倒排索引的功能是快速的返回要查找的单词包含在哪些文档中。
luncene的索引过程?索引的基本单位是文档,一个文档可以包含多个域,域值可以被索引也可以被单独存值,Luncene的索引过程就是从原始的文本中提取数据,并创建对应的document实例,一个document中包含了多个域,域是用来保存原始数据,然后分析过程将域处理成语汇单元添加到段文件中,核心过程可以总结成为,提取文档,分析文档,添加文档三个过程。提取文档过程,从各种文本中提取数据,对应的程序指的就是封装document的过程,分析文档,将要索引的数据封装成一个个的document对象之后会交给luncene来分析,分析过程会将数据分割成一个个的语汇单元,并做一些处理,比如对数据进行大小写转换,去除一些停词,无意义的词,最后生成语汇单元,最后对生成语汇单元写入到索引文件中。
来写一个对本地文件夹所有文件建索引的程序,对F盘下的所有文件的文件名建索引,生成的索引存放在F:\\Lucence\\Fdiskindex 目录下
添加pom依赖
<lucene.version>4.6.1</lucene.version>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>${lucene.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-highlighter -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>${lucene.version}</version>
</dependency>
f盘文件建索引
public>
private static Logger logger = Logger.getLogger(DiskIndex.class);
private String IndexOutputStr;
private String indexRootPath;
public String getIndexOutputStr() {return IndexOutputStr; }
public void setIndexOutputStr(String indexOutputStr) { IndexOutputStr
= indexOutputStr; }
public String getIndexRootPath() {return indexRootPath; }
public void setIndexRootPath(String indexRootPath) {this.indexRootPath = indexRootPath; }
private IndexWriter iwriter;
public void index() { Analyzer analyzer
= new StandardAnalyzer(Version.LUCENE_46); IndexWriterConfig config
= new IndexWriterConfig(Version.LUCENE_46, analyzer);try { Directory directory
= FSDirectory.open(new File(IndexOutputStr)); iwriter
= new IndexWriter(directory, config); File inputfile
= new File(indexRootPath); File[] files
= inputfile.listFiles();for (File file : files) {if(fileFilter(file)) { addDoc(file);
}
}
}
catch (IOException e) { e.printStackTrace();
logger.warn(
"打开文件异常"); }
}
private void addDoc(File file) {if (file.isDirectory()&&(!file.getPath().contains("RECYCLE.BIN"))) {try{ File[] filelist
= file.listFiles();for ( File afile: filelist ) { addDoc(afile);
} }
catch (Exception E){
}
}
else if (file.isFile()&&(!file.getPath().contains("RECYCLE.BIN"))) {try { indexFile(file);
}
catch (IOException e) { logger.info(
"索引文件出错 path = " + file.getPath()); }
}
}
private void close() throws IOException { iwriter.close();
}
private void indexFile(File file) throws IOException { logger.info(
" index file = "+ file.getPath()); String fileName
= file.getName(); String filePath
= file.getPath(); Long fileSize
= file.length(); Document doc
= new Document(); doc.add(
new Field("filename", fileName, TextField.TYPE_STORED)); doc.add(
new Field("filepath", filePath, TextField.TYPE_STORED)); doc.add(
new LongField("fileSize", fileSize, LongField.TYPE_STORED)); iwriter.addDocument(doc);
}
public static boolean fileFilter(File file){ Boolean flag
= true;if(file.getPath().contains("spark")){ flag
= false; }
if(file.getPath().contains("hive")){ flag
= false; }
return flag; }
public static void main(String[] args) throws IOException { DiskIndex index
= new DiskIndex(); index.setIndexRootPath(
"F:\\"); index.setIndexOutputStr(
"F:\\Lucence\\Fdiskindex"); index.index();
index.close();
}
}
再来一个搜索程序,搜索F盘下和redis有关的文件
public>
private Logger logger = Logger.getLogger(DiskIndex.class);
private DirectoryReader ireader = null;
private IndexSearcher isearcher = null;
private String indexdir = "F:\\Lucence\\Fdiskindex";
public void search(String queryField) {
Analyzer analyzer
= new StandardAnalyzer(Version.LUCENE_46); QueryParser parser
= new QueryParser(Version.LUCENE_46, "filename", analyzer); Directory directory
= null;try { directory
= FSDirectory.open(new File(indexdir)); DirectoryReader ireader
= DirectoryReader.open(directory); IndexSearcher isearcher
= new IndexSearcher(ireader);
Query query
= parser.parse(queryField);//query word ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
for (int i = 0; i < hits.length; i++) {
Document hitDoc = isearcher.doc(hits.doc);
System.out.println("____________________________");
System.out.println(hitDoc.get("filename"));
System.out.println(hitDoc.get("filepath"));
}
ireader.close();
directory.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
DiskSearch search = new DiskSearch();
search.search("redis");
}
}
查看返回结果
|
|
|