Lucene 简单API使用
本demo 简单模拟实现一个图书搜索功能。
- 模拟向数据库添加数据的时候,添加书籍索引。
- 提供搜索接口,支持按照书名,作者,内容进行搜索。
- 按默认规则排序返回搜索结果。
Jar依赖:
<properties> <lucene.version>4.6.1</lucene.version> </properties> <!-- lucence jar --> <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>
核心类:
/** * Alipay.com Inc. * Copyright (c) 2004-2015 All Rights Reserved/ */ package com.demo; import com.demo.convertor.BookConvertor; import com.demo.domain.BookDO; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryparser.classic.MultiFieldQueryParser; 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; import java.io.File; import java.io.IOException; import java.util.*; /** * lucence 简单demo * * @author baoxing.gbx * @version $Id:LucenceDemo.java, V 0.1 2015-11-11 14:15 baoxing.gbx Exp $$ */ public class LucenceDemo { /** 索引库存目录 */ private Directory directory; /** 分词器 */ private Analyzer analyzer; /** 索引写 */ private IndexWriter indexWriter; /** 索引查询 */ private IndexWriterConfig indexWriterConfig; /** 索引查询 */ private IndexSearcher searcher; /** 模拟数据库 */ private static Map<String, Object> dataBase = new HashMap<String, Object>(); /** * 初始化操作 * * @throws IOException */ public void init() throws IOException { // 1. 获取lucence索引目录 Properties properties = new Properties(); properties .load(LucenceDemo.class.getClassLoader().getResourceAsStream("lucence.properties")); directory = FSDirectory.open(new File((String) properties.get("path"))); // 2. 构造分词器 analyzer = new StandardAnalyzer(Version.LUCENE_40); // 3. 构造索引输入 indexWriterConfig = new IndexWriterConfig(Version.LUCENE_40, analyzer); indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE); indexWriter = new IndexWriter(directory, indexWriterConfig); } /** * 模拟数据库添加,同时添加索引 * * @param bookDO * @throws IOException */ public void addDoc(BookDO bookDO) throws IOException { // 数据库操作 dataBase.put(bookDO.getId() + "", bookDO); // 索引操作 Document document = BookConvertor.convert2Doc(bookDO); indexWriter.addDocument(document); } /** * 搜索 * * @param keyword * @return * @throws Exception */ public List<BookDO> search(String keyword) throws Exception { // 构造查询 IndexReader indexReader = IndexReader.open(directory); searcher = new IndexSearcher(indexReader); // 支持书名, 作者, 内容搜索 String[] fields = { "name", "author", "content" }; QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_40, fields, analyzer); queryParser.setDefaultOperator(QueryParser.AND_OPERATOR); Query query = queryParser.parse(keyword); // 最多给5个 TopDocs topdocs = searcher.search(query, 5); ScoreDoc[] scoreDocs = topdocs.scoreDocs; System.out.println("查询结果总数---" + topdocs.totalHits + "最大的评分--" + topdocs.getMaxScore()); List<BookDO> result = new ArrayList<BookDO>(); for (int i = 0; i < scoreDocs.length; i++) { int doc = scoreDocs[i].doc; Document document = searcher.doc(doc); System.out.println("docId--" + scoreDocs[i].doc + "---scors--" + scoreDocs[i].score + "---index--" + scoreDocs[i].shardIndex); result.add((BookDO) dataBase.get(document.get("id"))); } return result; } /** * Getter method for property <tt>analyzer</tt>. * * @return property value of analyzer */ public Analyzer getAnalyzer() { return analyzer; } /** * Setter method for property <tt>analyzer</tt>. * * @param analyzer value to be assigned to property analyzer */ public void setAnalyzer(Analyzer analyzer) { this.analyzer = analyzer; } /** * Getter method for property <tt>dataBase</tt>. * * @return property value of dataBase */ public Map<String, Object> getDataBase() { return dataBase; } /** * Setter method for property <tt>dataBase</tt>. * * @param dataBase value to be assigned to property dataBase */ public void setDataBase(Map<String, Object> dataBase) { this.dataBase = dataBase; } /** * Getter method for property <tt>directory</tt>. * * @return property value of directory */ public Directory getDirectory() { return directory; } /** * Setter method for property <tt>directory</tt>. * * @param directory value to be assigned to property directory */ public void setDirectory(Directory directory) { this.directory = directory; } /** * Getter method for property <tt>indexWriter</tt>. * * @return property value of indexWriter */ public IndexWriter getIndexWriter() { return indexWriter; } /** * Setter method for property <tt>indexWriter</tt>. * * @param indexWriter value to be assigned to property indexWriter */ public void setIndexWriter(IndexWriter indexWriter) { this.indexWriter = indexWriter; } /** * Getter method for property <tt>indexWriterConfig</tt>. * * @return property value of indexWriterConfig */ public IndexWriterConfig getIndexWriterConfig() { return indexWriterConfig; } /** * Setter method for property <tt>indexWriterConfig</tt>. * * @param indexWriterConfig value to be assigned to property indexWriterConfig */ public void setIndexWriterConfig(IndexWriterConfig indexWriterConfig) { this.indexWriterConfig = indexWriterConfig; } /** * Getter method for property <tt>searcher</tt>. * * @return property value of searcher */ public IndexSearcher getSearcher() { return searcher; } /** * Setter method for property <tt>searcher</tt>. * * @param searcher value to be assigned to property searcher */ public void setSearcher(IndexSearcher searcher) { this.searcher = searcher; } }
测试类:
/** * Alipay.com Inc. * Copyright (c) 2004-2015 All Rights Reserved/ */ package com.demo; import com.demo.domain.BookDO; import org.junit.Test; import junit.framework.TestCase; import java.util.List; /** * * @author baoxing.gbx * @version $Id:LucenceDemoTest.java, V 0.1 2015-11-11 15:21 baoxing.gbx Exp $$ */ public class LucenceDemoTest extends TestCase { LucenceDemo lucenceDemo = null; @Override protected void setUp() throws Exception { // 数据准备 lucenceDemo = new LucenceDemo(); lucenceDemo.init(); // 循环添加100本书 for (int i = 1; i <= 2; ++i) { BookDO bookDO = new BookDO(); bookDO.setId(i); bookDO.setAuthor("zhangsan" + i); bookDO.setName("Java program" + i); bookDO.setContent("Java是一种可以撰写跨平台应用程序的面向对象的程序设计开发语言"); lucenceDemo.addDoc(bookDO); } for (int i = 3; i <= 4; ++i) { BookDO bookDO = new BookDO(); bookDO.setId(i); bookDO.setAuthor("lisi" + i); bookDO.setName("Java program" + i); bookDO.setContent("Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网"); lucenceDemo.addDoc(bookDO); } for (int i = 5; i <= 6; ++i) { BookDO bookDO = new BookDO(); bookDO.setId(i); bookDO.setAuthor("wangwu" + i); bookDO.setName("Java program" + i); bookDO.setContent("同时拥有全球最大的开发者专业社"); lucenceDemo.addDoc(bookDO); } for (int i = 7; i <= 8; ++i) { BookDO bookDO = new BookDO(); bookDO.setId(i); bookDO.setAuthor("xiaoming" + i); bookDO.setName("C++ program" + i); bookDO.setContent("C++是在C语言的基础上开发的一种面向对象编程语言"); lucenceDemo.addDoc(bookDO); } } /** * 测试根据书名查找 */ @Test public void testNameSearch() { try { lucenceDemo.getIndexWriter().close(); List<BookDO> bookDOs = lucenceDemo.search("Java"); System.out.println("查询到" + bookDOs.size() + "本相关书籍。 详细信息如下:"); for (int i = 0; i < bookDOs.size(); ++i) { System.out.println(bookDOs.get(i).toString()); } } catch (Exception e) { assertTrue(e.getMessage(), false); } } /** * 测试根据作者查找 */ @Test public void testAuthorSearch() { try { lucenceDemo.getIndexWriter().close(); List<BookDO> bookDOs = lucenceDemo.search("zhangsan1"); System.out.println("查询到" + bookDOs.size() + "本相关书籍。 详细信息如下:"); for (int i = 0; i < bookDOs.size(); ++i) { System.out.println(bookDOs.get(i).toString()); } } catch (Exception e) { assertTrue(e.getMessage(), false); } } /** * 测试根据内同查找 */ @Test public void testContentSearch() { try { lucenceDemo.getIndexWriter().close(); List<BookDO> bookDOs = lucenceDemo.search("开发"); System.out.println("查询到" + bookDOs.size() + "本相关书籍。 详细信息如下:"); for (int i = 0; i < bookDOs.size(); ++i) { System.out.println(bookDOs.get(i).toString()); } } catch (Exception e) { assertTrue(e.getMessage(), false); } } /** * 测试多条件查找 */ @Test public void testMutiSearch() { try { lucenceDemo.getIndexWriter().close(); List<BookDO> bookDOs = lucenceDemo.search("zhangsan1 C++"); System.out.println("查询到" + bookDOs.size() + "本相关书籍。 详细信息如下:"); for (int i = 0; i < bookDOs.size(); ++i) { System.out.println(bookDOs.get(i).toString()); } bookDOs = lucenceDemo.search("zhangsan1 Java"); System.out.println("查询到" + bookDOs.size() + "本相关书籍。 详细信息如下:"); for (int i = 0; i < bookDOs.size(); ++i) { System.out.println(bookDOs.get(i).toString()); } } catch (Exception e) { assertTrue(e.getMessage(), false); } } }
代码地址 :https://github.com/EstarG/lucenceDemo