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

 

posted @ 2015-11-11 20:28  E_star  阅读(691)  评论(0编辑  收藏  举报