• 【Lucene4.8教程之一】使用Lucene4.8进行索引及搜索的基本操作



    在Lucene对文本进行处理的过程中,可以大致分为三大部分:

    1、索引文件:提取文档内容并分析,生成索引

    2、搜索内容:搜索索引内容,根据搜索关键字得出搜索结果

    3、分析内容:对搜索词汇进行分析,生成Quey对象。


    注:事实上,除了最基本的完全匹配搜索以外,其它都需要在搜索前进行分析。

    如不加分析步骤,则搜索JAVA,是没有结果的,因为在索引过程中已经将词汇均转化为小写,而此处搜索时则要求关键字完全匹配。

    使用了QueryParser类以后,则根据Analyzer的具体实现类,对搜索词汇进行分析,如大小写转换,java and ant等的搜索词解释等。


    一、索引文件

    基本步骤如下:

    1、创建索引库IndexWriter

    2、根据文件创建文档Document

     3、向索引库中写入文档内容

    package com.ljh.search.index;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.document.LongField;
    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;
    
    // 1、创建索引库IndexWriter
    // 2、根据文件创建文档Document
    // 3、向索引库中写入文档内容
    
    public class IndexFiles {
    
    	public static void main(String[] args) throws IOException {
    
    		String usage = "java IndexFiles"
    				+ " [-index INDEX_PATH] [-docs DOCS_PATH] 
    
    "
    				+ "This indexes the documents in DOCS_PATH, creating a Lucene index"
    				+ "in INDEX_PATH that can be searched with SearchFiles";
    
    		String indexPath = null;
    		String docsPath = null;
    		for (int i = 0; i < args.length; i++) {
    			if ("-index".equals(args[i])) {
    				indexPath = args[i + 1];
    				i++;
    			} else if ("-docs".equals(args[i])) {
    				docsPath = args[i + 1];
    				i++;
    			}
    		}
    
    		if (docsPath == null) {
    			System.err.println("Usage: " + usage);
    			System.exit(1);
    		}
    
    		final File docDir = new File(docsPath);
    		if (!docDir.exists() || !docDir.canRead()) {
    			System.out
    					.println("Document directory '"
    							+ docDir.getAbsolutePath()
    							+ "' does not exist or is not readable, please check the path");
    			System.exit(1);
    		}
    
    		IndexWriter writer = null;
    		try {
    			// 1、创建索引库IndexWriter
    			writer = getIndexWriter(indexPath);
    			index(writer, docDir);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			writer.close();
    		}
    
    	}
    
    	private static IndexWriter getIndexWriter(String indexPath)
    			throws IOException {
    
    		Directory indexDir = FSDirectory.open(new File(indexPath));
    
    		IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_48,
    				new StandardAnalyzer(Version.LUCENE_48));
    
    		IndexWriter writer = new IndexWriter(indexDir, iwc);
    
    		return writer;
    	}
    
    	private static void index(IndexWriter writer, File file) throws IOException {
    
    		if (file.isDirectory()) {
    			String[] files = file.list();
    			if (files != null) {
    				for (int i = 0; i < files.length; i++) {
    					index(writer, new File(file, files[i]));
    				}
    			}
    		} else {
    			// 2、根据文件创建文档Document
    			Document doc = new Document();
    			Field pathField = new StringField("path", file.getPath(),
    					Field.Store.YES);
    			doc.add(pathField);
    			doc.add(new LongField("modified", file.lastModified(),
    					Field.Store.NO));
    			doc.add(new TextField("contents", new FileReader(file)));
    			System.out.println("Indexing " + file.getName());
    			
    			// 3、向索引库中写入文档内容
    			writer.addDocument(doc);
    		}
    
    	}
    
    }
    

    (1)使用“java indexfiles -index d:/index -docs d:/tmp”运行程序,索引d:/tmp中的文件,并将索引文件放置到d:/index。

    (2)上述生成的索引文件可以使用Luke进行查看。目前Luke已迁移至github进行托管。


    二、搜索文件

    1、打开索引库IndexSearcher
    2、根据关键词进行搜索
    3、遍历结果并处理

    package com.ljh.search.search;
    
    //1、打开索引库IndexSearcher
    //2、根据关键词进行搜索
    //3、遍历结果并处理
    import java.io.File;
    import java.io.IOException;
    
    import org.apache.lucene.index.DirectoryReader;
    import org.apache.lucene.index.IndexReader;
    import org.apache.lucene.index.Term;
    import org.apache.lucene.search.IndexSearcher;
    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;
    
    public class Searcher {
    	public static void main(String[] args) throws IOException {
    
    		String indexPath = null;
    		String term = null;
    		for (int i = 0; i < args.length; i++) {
    			if ("-index".equals(args[i])) {
    				indexPath = args[i + 1];
    				i++;
    			} else if ("-term".equals(args[i])) {
    				term = args[i + 1];
    				i++;
    			}
    		}
    
    		System.out.println("Searching " + term + " in " + indexPath);
    
    		// 1、打开索引库
    		Directory indexDir = FSDirectory.open(new File(indexPath));
    		IndexReader ir = DirectoryReader.open(indexDir);
    		IndexSearcher searcher = new IndexSearcher(ir);
    
    		// 2、根据关键词进行搜索
    		TopDocs docs = searcher.search(
    				new TermQuery(new Term("contents", term)), 20);
    
    		// 3、遍历结果并处理
    		ScoreDoc[] hits = docs.scoreDocs;
    		System.out.println(hits.length);
    		for (ScoreDoc hit : hits) {
    			System.out.println("doc: " + hit.doc + " score: " + hit.score);
    		}
    
    		ir.close();
    
    	}
    
    }
    

    三、分析

    事实上,除了最基本的完全匹配搜索以外,其它都需要在搜索前进行分析。

    如不加分析步骤,则搜索JAVA,是没有结果的,因为在索引过程中已经将词汇均转化为小写,而此处搜索时则要求关键字完全匹配。

    使用了QueryParser类以后,则根据Analyzer的具体实现类,对搜索词汇进行分析,如大小写转换,java and ant等的搜索词解释等。

    分析过程有2个基本步骤:

    1、生成QueryParser对象

    2、调用QueryParser.parse()生成Query()对象。

    具体代码,将下述代码:

    		// 2、根据关键词进行搜索
    		TopDocs docs = searcher.search(
    				new TermQuery(new Term("contents", term)), 20);
    用以下代替:

    		// 2、根据关键词进行搜索
    		/*TopDocs docs = searcher.search(
    				new TermQuery(new Term("contents", term)), 10);*/
    		QueryParser parser = new QueryParser(Version.LUCENE_48, "contents", new SimpleAnalyzer(Version.LUCENE_48));
    		Query query = null;
    		try {
    			query = parser.parse(term);
    		} catch (ParseException e) {
    			e.printStackTrace();
    		}
    		TopDocs docs = searcher.search(query, 30);



  • 相关阅读:
    mp4v2 基本知识
    iperf3.0 hisi uclib 交叉编译
    几个性能测试工具
    单元测试和测试驱动开发的一些常见问题总结
    线程上下文切换的性能损耗测试
    TDD中的单元测试写多少才够?
    AOP学习总结
    ATDD和TDD的区别是什么?
    [转帖]双剑合璧:CPU+GPU异构计算完全解析
    推荐《程序员的四种类型》
  • 原文地址:https://www.cnblogs.com/jediael/p/4304126.html
Copyright © 2020-2023  润新知