初识lunece(同义词检索)

1.首先创建索引

package com.sunmap.analyzer;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
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;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 *    创建索引
 */
public class MyIndexer {
    public static void createIndex(String indexPath) throws IOException {
        Directory directory = FSDirectory.open(new File(indexPath));
        Analyzer analyzer = new IKAnalyzer();

        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46,
                analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, config);
        Document document1 = new Document();
        document1.add(new TextField("title", "thinkpad超极本笔记本中的战斗机", Field.Store.YES));
        indexWriter.addDocument(document1);

        Document document2 = new Document();
        document2.add(new TextField("title", "用户可以在这里配置自己的扩展字典", Field.Store.YES));
        indexWriter.addDocument(document2);

        Document document3 = new Document();
        document3.add(new TextField("title", "您可以参考分词器源码", Field.Store.YES));
        indexWriter.addDocument(document3);

        Document document4 = new Document();
        document4.add(new TextField("title","第一台计算机是美国军方定制,专门为了计算弹道和射击特性表面而研制的,承担开发任务的“莫尔小组”由四位科学家和工程师埃克特、莫克利、戈尔斯坦、博克斯组成。1946年这台计算机主要元器件采用的是电子管。该机使用了1500"
                                + "个继电器,18800个电子管,占地170m2,重量重达30多吨,耗电150KW,造价48万美元。这台计算机每秒能完成5000次加法运算,400次乘法运算,比当时最快的计算工具快300倍,是继电器计算机的1000倍、手工计算的20万倍。"
                                + "用今天的标准看,它是那样的“笨拙”和“低级”,其功能远不如一只掌上可编程计算器,但它使科学家们从复杂的计算中解脱出来,它的诞生标志着人类进入了一个崭新的信息革命时代。",
                                Field.Store.YES));
        indexWriter.addDocument(document4);
        indexWriter.close();
    }
}

2.创建一个检索类:

package com.sunmap.analyzer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class MySearcher {
    public static List<String> searchIndex(String keyword, String indexPath)
            throws IOException, ParseException {
        List<String> result = new ArrayList<>();
        IndexSearcher indexSearcher = null;
        IndexReader indexReader = DirectoryReader.open(FSDirectory
                .open(new File(indexPath)));
        indexSearcher = new IndexSearcher(indexReader);
        Analyzer analyzer = new IKAnalyzer();
        QueryParser queryParser = new QueryParser(Version.LUCENE_46, "title",analyzer);
        Query query = queryParser.parse(keyword);
        TopDocs td = indexSearcher.search(query, 10);
        for (int i = 0; i < td.totalHits; i++) {
            System.out.println(td.scoreDocs[i].score);
            Document document = indexSearcher.doc(td.scoreDocs[i].doc);
            result.add(document.get("title"));
        }
        return result;
    }
}

3.同义词检索:

package com.sunmap.analyzer;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.analysis.synonym.SynonymFilterFactory;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.util.FilesystemResourceLoader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class AnalyzerUtil {

    /**
     * 
     * 此方法描述的是:进行中文拆分
     */
    public static String analyzeChinese(String input, boolean userSmart)
            throws IOException {
        StringBuffer sb = new StringBuffer();
        StringReader reader = new StringReader(input.trim());
        IKSegmenter ikSeg = new IKSegmenter(reader, userSmart);// true 用智能分词 ,false细粒度
        for (Lexeme lexeme = ikSeg.next(); lexeme != null; lexeme = ikSeg
                .next()) {
            sb.append(lexeme.getLexemeText()).append(" ");
        }
        return sb.toString();
    }

    /**
     * 
     * 此方法描述的是:对传入的字符串进行同义词匹配,返回有同义词的TokenStream
     */
    public static TokenStream convertSynonym(String input) throws IOException {
        Version ver = Version.LUCENE_46;
        Map<String, String> filterArgs = new HashMap<String, String>();
        filterArgs.put("luceneMatchVersion", ver.toString());
        //同义词词库位置
        filterArgs.put("synonyms", "config/synonyms.txt");
        filterArgs.put("expand", "true");
        
        
        
        SynonymFilterFactory factory = new SynonymFilterFactory(filterArgs);
        factory.inform(new FilesystemResourceLoader());
        Analyzer ikAnalyzer = new IKAnalyzer();
        TokenStream ts = factory.create(ikAnalyzer.tokenStream("someField", input));
        return ts;
    }

    /**
     * 
     * 此方法描述的是:将tokenstream解析成字符串
     */
    public static String displayTokens(TokenStream ts) throws IOException {
        StringBuffer sb = new StringBuffer();
        CharTermAttribute termAttr = ts.addAttribute(CharTermAttribute.class);
        ts.reset();
        while (ts.incrementToken()) {
            String token = termAttr.toString();
            sb.append(token);
        }
        ts.end();
        ts.close();
        return sb.toString();
    }

    public static void main(String[] args) {
        
        String indexPath = "/home/share/study/index_test";
        String input = "电脑";
        System.out.println("**********************");
        try {
            String result = displayTokens(convertSynonym(analyzeChinese(input,
                    true)));
            /**
             * 
             * 注意这块
             * 同义词检索就是把将要检索的词变成它的同义词和自己的合成词进行检索
             * 
             * */
            System.out.println(result);
//            String result = input;
//            MyIndexer.createIndex(indexPath);
            List<String> docs = MySearcher.searchIndex(result, indexPath);
            for (String string : docs) {
                System.out.println(string);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

**********************
加载扩展词典:ext.dic
加载扩展停止词典:stopword.dic
超极本计算机电脑
0.17161283
0.087962404
thinkpad超极本笔记本中的战斗机
第一台计算机是美国军方定制,专门为了计算弹道和射击特性表面而研制的,承担开发任务的“莫尔小组”由四位科学家和工程师埃克特、莫克利、戈尔斯坦、博克斯组成。1946年这台计算机主要元器件采用的是电子管。该机使用了1500个继电器,18800个电子管,占地170m2,重量重达30多吨,耗电150KW,造价48万美元。这台计算机每秒能完成5000次加法运算,400次乘法运算,比当时最快的计算工具快300倍,是继电器计算机的1000倍、手工计算的20万倍。用今天的标准看,它是那样的“笨拙”和“低级”,其功能远不如一只掌上可编程计算器,但它使科学家们从复杂的计算中解脱出来,它的诞生标志着人类进入了一个崭新的信息革命时代。

同义词词库synonyms.txt内容:

我,俺,hankcs
似,is,are => 是
好人,好心人,热心人
超极本,计算机,电脑

好人,好心人,热心人

代表同义词;

似,is,are => 是

似,is,are 可以转意为是;

想的都是好
原文地址:https://www.cnblogs.com/freezone/p/5239207.html