Lucene实现简单的全文检索
2017-11-06 14:53
281 查看
一、索引小程序
1. 将所需要的lucene包导入到项目里。
2. 首先在LuceneIndex里new一个class,名字叫做Indexer。
3. 然后,在LuceneIndex工程里新建一个文件夹,叫做raw。
4. 接下来,在raw文件夹里新建两个utf-8编码的txt文件。比如第一个文件命名为hello.txt,内容为"Hello",第二个文件命名为nihao.txt,内容为"你好"。这里要注意的是,上面的代码是针对中文搜索的问题使用了utf-8编码,所以要求文件也是utf-8的编码。
5. 写入如下代码:
二、检索小程序
下面我们就要用这个index来检索了。
new一个class,命名为Searcher。然后在里面写入如下代码:
三、遍历文件系统
这是一个简单的Lucene演示程序,只能索引同一目录下的txt文件,下面我来介绍一种遍历文件系统并且索引.txt文件的方法。
这个方法很简单,就是一个递归实现的深度优先遍历。
1. 将所需要的lucene包导入到项目里。
2. 首先在LuceneIndex里new一个class,名字叫做Indexer。
3. 然后,在LuceneIndex工程里新建一个文件夹,叫做raw。
4. 接下来,在raw文件夹里新建两个utf-8编码的txt文件。比如第一个文件命名为hello.txt,内容为"Hello",第二个文件命名为nihao.txt,内容为"你好"。这里要注意的是,上面的代码是针对中文搜索的问题使用了utf-8编码,所以要求文件也是utf-8的编码。
5. 写入如下代码:
import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.io.*; 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.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; /** * @author csl * @description: * 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser * 作用:简单的索引建立 */ public class Indexer { public static Version luceneVersion = Version.LATEST; /** * 建立索引 */ public static void createIndex(){ IndexWriter writer = null; try{ //1、创建Directory //Directory directory = new RAMDirectory();//创建内存directory Directory directory = FSDirectory.open(Paths.get("index"));//在硬盘上生成Directory00 //2、创建IndexWriter IndexWriterConfig iwConfig = new IndexWriterConfig( new StandardAnalyzer()); writer = new IndexWriter(directory, iwConfig); //3、创建document对象 Document document = null; //4、为document添加field对象 File f = new File("raw");//索引源文件位置 for (File file:f.listFiles()){ document = new Document(); document.add(new StringField("path", f.getName(),Field.Store.YES)); System.out.println(file.getName()); document.add(new StringField("name", file.getName(),Field.Store.YES)); InputStream stream = Files.newInputStream(Paths.get(file.toString())); document.add(new TextField("content", new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));//textField内容会进行分词 //document.add(new TextField("content", new FileReader(file))); // 如果不用utf-8编码的话直接用这个就可以了 writer.addDocument(document); } }catch(Exception e){ e.printStackTrace(); }finally{ //6、使用完成后需要将writer进行关闭 try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) throws IOException { createIndex(); } }6. 最后,运行Indexer.java。会看到索引建立完成。LuceneIndex工程下多了一个index文件夹。
二、检索小程序
下面我们就要用这个index来检索了。
new一个class,命名为Searcher。然后在里面写入如下代码:
import java.nio.file.Paths; import java.io.*; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; 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.FSDirectory; import org.apache.lucene.util.Version; /** * @author csl * @description: * 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser * 作用:使用索引搜索文件 */ public class Searcher { public static Version luceneVersion = Version.LATEST; /** * 查询内容 */ public static String indexSearch(String keywords){ String res = ""; DirectoryReader reader = null; try{ // 1、创建Directory Directory directory = FSDirectory.open(Paths.get("index"));//在硬盘上生成Directory // 2、创建IndexReader reader = DirectoryReader.open(directory); // 3、根据IndexWriter创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); // 4、创建搜索的query // 创建parse用来确定搜索的内容,第二个参数表示搜索的域 QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段 Query query = parser.parse(keywords);//被搜索的内容 // 5、根据Searcher返回TopDocs TopDocs tds = searcher.search(query, 20);//查询20条记录 // 6、根据TopDocs获取ScoreDoc ScoreDoc[] sds = tds.scoreDocs; // 7、根据Searcher和ScoreDoc获取搜索到的document对象 int cou=0; for(ScoreDoc sd:sds){ cou++; Document d = searcher.doc(sd.doc); // 8、根据document对象获取查询的字段值 /** 查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/ res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n"; } }catch(Exception e){ e.printStackTrace(); }finally{ //9、关闭reader try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return res; } public static void main(String[] args) throws IOException { System.out.println(indexSearch("hi")); //搜索的内容可以修改 } }搜索内容为"Hello"时,搜索结果为内容包含"Hello"的hello.txt。
三、遍历文件系统
这是一个简单的Lucene演示程序,只能索引同一目录下的txt文件,下面我来介绍一种遍历文件系统并且索引.txt文件的方法。
这个方法很简单,就是一个递归实现的深度优先遍历。
import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.io.*; import org.apache.lucene.analysis.standard.StandardAnalyzer; 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.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; public class Indexall { static int numIndexed=0; //索引 private static void indexFile(IndexWriter writer,File f) throws IOException { if(f.isHidden()||!f.exists()||!f.canRead()) { return; } System.out.println("Indexing"+f.getCanonicalPath()); Document document = new Document(); document.add(new StringField("path", f.getName(),Field.Store.YES)); System.out.println(f.getName()); document.add(new StringField("name", f.getName(),Field.Store.YES)); InputStream stream = Files.newInputStream(Paths.get(f.toString())); document.add(new TextField("content", new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));//textField内容会进行分词 //document.add(new TextField("content", new FileReader(file))); 如果不用utf-8编码的话直接用这个就可以了 writer.addDocument(document); } //深度优先遍历文件系统并索引.txt文件 private static int indexDirectory(IndexWriter writer,File dir) throws IOException { File[] files=dir.listFiles(); for(int i=0;i<files.length;i++) { File f=files[i]; System.out.println(f.getAbsolutePath()); if(f.isDirectory()) { indexDirectory(writer,f); } else if(f.getName().endsWith(".txt")) { indexFile(writer,f);//递归 numIndexed+=1; } } return numIndexed; } //创建IndexWriter并开始文件系统遍历 public static int index(File indexDir,File dataDir) throws IOException { if(!dataDir.exists()||!dataDir.isDirectory()) { throw new IOException(dataDir+"does not exist or is not a directory!"); } Directory directory = FSDirectory.open(Paths.get("index")); IndexWriterConfig iwConfig = new IndexWriterConfig( new StandardAnalyzer()); IndexWriter writer = new IndexWriter(directory, iwConfig); int numIndexed=indexDirectory(writer,dataDir); writer.close(); return numIndexed; } public static void main(String[] args) throws Exception { File indexDir=new File("index"); File dataDir=new File("raw"); int numIndexed=index(indexDir,dataDir); System.out.println("Indexing " + numIndexed + " files"); } }
相关文章推荐
- 仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 火力全开——仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 站内搜索------仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 火力全开——仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 使用compass+lucene实现简单的全文检索功能
- 火力全开——仿造Baidu简单实现基于Lucene.net的全文检索的功能
- 使用lucene实现简单的全文检索
- sql简单实现全文检索及匹配度排序
- 使用Lucene对doc、docx、pdf、txt文档进行全文检索功能的实现
- lucene--1.lucene实现全文检索的流程
- 用PHP调用Lucene包来实现全文检索(转)
- lucene 实现word,pdf全文检索源码
- 使用Lucene-Spatial实现集成地理位置的全文检索
- 用PHP调用Lucene包来实现全文检索
- [转]用PHP调用Lucene包来实现全文检索
- 仿造百度实现基于Lucene.net全文检索
- 使用lucene实现全文检索
- Oracle_C# 实现 Oracle Text(全文检索)的一个简单例子
- android+lucene实现全文检索并高亮关键字