看完本系列前面的文章之后,之后的文章就简单多了。如果还看不懂本文,请回过头看前面四篇文章,前面四篇文章关联性较大,可以穿插着看。

直接上完整代码:

public class TestLuceneHighLight {

    public static void main(String[] args) throws Exception {
        // 1. 准备中文分词器
        Analyzer analyzer = new SmartChineseAnalyzer();

        // 2. 索引
        List<String> productNames = new ArrayList<>();
        productNames.add("飞利浦led灯泡e27螺口暖白球泡灯家用照明超亮节能灯泡转色温灯泡");
        productNames.add("飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄光源Lamp");
        productNames.add("雷士照明 LED灯泡 e27大螺口节能灯3W球泡灯 Lamp led节能灯泡");
        productNames.add("飞利浦 led灯泡 e27螺口家用3w暖白球泡灯节能灯5W灯泡LED单灯7w");
        productNames.add("飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明光源lamp单灯");
        productNames.add("飞利浦蒲公英护眼台灯工作学习阅读节能灯具30508带光源");
        productNames.add("欧普照明led灯泡蜡烛节能灯泡e14螺口球泡灯超亮照明单灯光源");
        productNames.add("欧普照明led灯泡节能灯泡超亮光源e14e27螺旋螺口小球泡暖黄家用");
        productNames.add("聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮光源");
        Directory index = createIndex(analyzer, productNames);

        // 3. 查询器
        String keyword = "护眼带光源";
        Query query = new QueryParser("name", analyzer).parse(keyword);

        // 4. 搜索
        IndexReader reader = DirectoryReader.open(index);
        IndexSearcher searcher = new IndexSearcher(reader);
        int numberPerPage = 1000;
        System.out.printf("当前一共有%d条数据%n", productNames.size());
        System.out.printf("查询关键字是:\"%s\"%n", keyword);
        ScoreDoc[] hits = searcher.search(query, numberPerPage).scoreDocs;

        // 5. 显示查询结果
        showSearchResults(searcher, hits, query, analyzer);
        // 6. 关闭查询
        reader.close();
    }

    private static void showSearchResults(IndexSearcher searcher, ScoreDoc[] hits, Query query, Analyzer analyzer)
            throws Exception {
        System.out.println("找到 " + hits.length + " 个命中.");
        System.out.println("序号\t匹配度得分\t结果");

        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

        for (int i = 0; i < hits.length; ++i) {
            ScoreDoc scoreDoc = hits[i];
            int docId = scoreDoc.doc;
            Document d = searcher.doc(docId);
            List<IndexableField> fields = d.getFields();
            System.out.print((i + 1));
            System.out.print("\t" + scoreDoc.score);
            for (IndexableField f : fields) {
                TokenStream tokenStream = analyzer.tokenStream(f.name(), new StringReader(d.get(f.name())));
                String fieldContent = highlighter.getBestFragment(tokenStream, d.get(f.name()));
                System.out.print("\t" + fieldContent);
            }
            System.out.println("<br>");
        }
    }

    private static Directory createIndex(Analyzer analyzer, List<String> products) throws IOException {
        Directory index = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter writer = new IndexWriter(index, config);

        for (String name : products) {
            addDoc(writer, name);
        }
        writer.close();
        return index;
    }

    private static void addDoc(IndexWriter w, String name) throws IOException {
        Document doc = new Document();
        doc.add(new TextField("name", name, Field.Store.YES));
        w.addDocument(doc);
    }
}

下面是运行结果:

当前一共有9条数据
查询关键字是:"护眼带光源"
找到 5 个命中.
序号	匹配度得分	结果
1	3.3918462	飞利浦蒲公英<span style='color:red'>护</span><span style='color:red'>眼</span>台灯工作学习阅读节能灯具30508<span style='color:red'>带</span><span style='color:red'>光源</span><br>
2	0.27233043	飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄<span style='color:red'>光源</span>Lamp<br>
3	0.26714253	飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明<span style='color:red'>光源</span>lamp单灯<br>
4	0.26714253	聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮<span style='color:red'>光源</span><br>
5	0.25733808	欧普照明led灯泡节能灯泡超亮<span style='color:red'>光源</span>e14e27螺旋螺口小球泡暖黄家用<br>

代码如果有看不懂的,可以看我上一篇文章,有详细解释,注意本文的代码和上一篇的代码的区别,这就是实现高亮的代码。

Q.E.D.


擅长前端的Java程序员