zoukankan      html  css  js  c++  java
  • 搜索引擎Lucene之皮毛

      一、Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。

      二、搜索引擎这个东西还是很大的,我这里只是用了一点点皮毛,有兴趣还是去学习一下Solr

      三、简易版的搜索实现依赖包

        <dependency>
                <groupId>com.github.magese</groupId>
                <artifactId>ik-analyzer</artifactId>
                <version>7.4.0</version>
            </dependency>

      四、代码

    import com.alibaba.fastjson.JSONObject;
    import org.apache.lucene.analysis.TokenStream;
    import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.document.TextField;
    import org.apache.lucene.index.*;
    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.store.Directory;
    import org.apache.lucene.store.RAMDirectory;
    import org.wltea.analyzer.lucene.IKAnalyzer;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Funtion: 搜索引擎核心工具类.
     * <p>
     * Date: 2018/9/18 14:08
     */
    public class LuceneUtils {
        //索引字段
        private static final String INDEX_NAME = "searchName";
        //用于传输实体类型
        public static final String ENTITY_TYPE = "entityType";
        //关键词,用于前端
        public static final String KEY_WORDS = "keyWords";
        private static final Integer VIEW_NUMBER = 100;
    
        /**
         * 搜索引擎,查询结果
         * @param searchName
         * @param objects
         * @return
         * @throws Exception
         */
        public static List<JSONObject> search(String searchName, List<Object> objects) throws Exception {
            //1、准备中文分词器
            IKAnalyzer analyzer = new IKAnalyzer();
            //2、获取关键词,用于前端使用
            List<String> keywords = getKeywords(searchName, analyzer);
            //3、索引
            Directory directory = addIndex(analyzer, objects);
            //4、查询器
            Query query = new QueryParser(INDEX_NAME, analyzer).parse(searchName);
            //5、搜索
            IndexReader reader = DirectoryReader.open(directory);
            IndexSearcher searcher = new IndexSearcher(reader);
            ScoreDoc[] scoreDocs = searcher.search(query, VIEW_NUMBER).scoreDocs;
            //6、查询结果
            List<JSONObject> results = getResults(searcher, scoreDocs, keywords);
            //7、关闭查询
            reader.close();
            directory.close();
            //8、返回结果
            return results;
        }
    
        /**
         * 获取关键词
         * @param searchName
         * @param analyzer
         * @return
         * @throws IOException
         */
        private static List<String> getKeywords(String searchName, IKAnalyzer analyzer) throws IOException {
            List<String> keyWords = new ArrayList<>();
            TokenStream tokenStream = analyzer.tokenStream("", searchName);
            CharTermAttribute attribute = tokenStream.getAttribute(CharTermAttribute.class);
            tokenStream.reset();
            while (tokenStream.incrementToken()) {
                keyWords.add(attribute.toString());
            }
            tokenStream.close();
            return keyWords;
        }
    
        /**
         * 获取搜索结果
         * @param searcher
         * @param scoreDocs
         * @return
         * @throws Exception
         */
        private static List<JSONObject> getResults(IndexSearcher searcher, ScoreDoc[] scoreDocs, List<String> keyWords) throws Exception {
            if (scoreDocs != null && scoreDocs.length > 0) {
                IKAnalyzer analyzer = new IKAnalyzer();
                List<JSONObject> objects = new ArrayList<>();
                //遍历文本
                for (ScoreDoc scoreDoc:scoreDocs) {
                    Document document = searcher.doc(scoreDoc.doc);
                    List<IndexableField> fields = document.getFields();
                    if (fields != null && !fields.isEmpty()) {
                        //获取指定索引数据
                        JSONObject jsonObject = JSONObject.parseObject(document.get(INDEX_NAME));
                        jsonObject.put(ENTITY_TYPE, document.get(ENTITY_TYPE));
                        jsonObject.put(KEY_WORDS, keyWords);
                        objects.add(jsonObject);
                    }
                }
                return objects;
            }
            return null;
        }
    
        /**
         * 添加索引
         * @param analyzer
         * @param objects
         * @return
         * @throws IOException
         */
        private static Directory addIndex(IKAnalyzer analyzer, List<Object> objects) throws IOException {
            //使用内存方式
            Directory directory = new RAMDirectory();
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
            IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
            if (objects != null && !objects.isEmpty()) {
                //添加索引
                for (Object object:objects) {
                    Document document = new Document();
                    document.add(new TextField(INDEX_NAME, JSONObject.toJSONString(object), Field.Store.YES));
                    document.add(new TextField(ENTITY_TYPE, object.getClass().getName(), Field.Store.YES));
                    indexWriter.addDocument(document);
                }
            }
            indexWriter.close();
            return directory;
        }
    }

      

  • 相关阅读:
    题解 SP27102/UVA1747 【Swap Space】
    题解 P1453 【城市环路】
    题解 P5587 【打字练习】
    题解 P5594 【【XR-4】模拟赛】
    git add 的一点说明
    理解 Git 的基本概念 ( Merging Collaborating Rebasing)
    windows 上 Python 通过 SCP 连接linux server
    Neo4j CQL | WITH用法
    Neo4j CQL |create &merge
    Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format(请使用f-string格式化字符串)
  • 原文地址:https://www.cnblogs.com/ll409546297/p/9724845.html
Copyright © 2011-2022 走看看