zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【转载】行走在镜面的边缘
    Marked
    初赛知识
    【连载中】另一个宇宙
    【OI学习注意事项】
    欢迎
    [很杂的杂项] Yes, Prime Minister长难句大赏(持续更新中)
    [题解] HH的项链
    [题解] SP2713&P1415 线段树区间每个数开方+区间和
    [题解]EER1迫害
  • 原文地址:https://www.cnblogs.com/E-star/p/4957285.html
Copyright © 2011-2022 走看看