Lucene之高亮显示-yellowcong

来源:互联网 发布:袁劲松 思维 知乎 编辑:程序博客网 时间:2024/05/29 17:45

高亮显示,在WEB的查询和检索中,会经常的用到,我们需要通过高亮的操作来显示关键字。操作的时候,将高亮的数据处理后,封装成对象后,再返回给调用者。

高亮案例

将带有yellowcong用户名的,高亮显示

private static void testHight(){        IndexReader reader = null;        try {            reader = getIndexReader();            //获取查寻条件            QueryParser parser = getQueryParser();            //将空格默认 定义为AND//      parse.setDefaultOperator(Operator.AND);            //设定第一个* 可以匹配            parser.setAllowLeadingWildcard(true);            //精确String 类型查询            System.out.println("-------------查询用户名为yellowcong的数据-------------");            //精确查询,根据名称来直接            Query query = parser.parse("username:yellowcong");            // 1.格式化对象,设置前缀和后缀            SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='red'>","</font>");            // 2.关键词对象(是highlight 的包)            Scorer scorer = new QueryScorer(query);            // 3. 高亮对象            Highlighter highlighter = new Highlighter(formatter, scorer);            IndexSearcher searcher = new IndexSearcher(reader);            TopDocs topDocs =searcher.search(query, 100);            System.out.println("查询到的条数\t"+topDocs.totalHits);            for(ScoreDoc score :topDocs.scoreDocs){                Document doc = reader.document(score.doc);                //给关键字添加高亮                String result = highlighter.getBestFragment(                        new StandardAnalyzer(Version.LUCENE_45),                         "username", //字段                        doc.get("username")); //高亮内容                System.out.println(result);            }            coloseReader(reader);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            coloseReader(reader);        }    }

测试结果,带有yellowcong的都高亮了。
这里写图片描述

完整代码

package com.yellowcong.index;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.IntField;import org.apache.lucene.document.LongField;import org.apache.lucene.document.StringField;import org.apache.lucene.document.TextField;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.Term;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.NumericRangeQuery;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.search.highlight.Highlighter;import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;import org.apache.lucene.search.highlight.QueryScorer;import org.apache.lucene.search.highlight.Scorer;import org.apache.lucene.search.highlight.SimpleHTMLFormatter;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.util.Version;/** * 创建用户:狂飙的yellowcong<br/> * 创建时间:下午5:27:50<br/> * 创建日期:2017年12月2日<br/> * 机能概要: */public class Demo3 {    private static List<Passage> psgList = null;    // 写对象    private static IndexWriter writer = null;    public static void main(String[] args) throws Exception {        // 删除 所有索引        deleteAll();        // 建立索引        index();    }    /**     *      * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月3日<br/>     * 创建时间:下午10:09:53<br/>     * 机能概要:高亮案例     */    private static void testHight(){        IndexReader reader = null;        try {            reader = getIndexReader();            //获取查寻条件            QueryParser parser = getQueryParser();            //将空格默认 定义为AND//      parse.setDefaultOperator(Operator.AND);            //设定第一个* 可以匹配            parser.setAllowLeadingWildcard(true);            //精确String 类型查询            System.out.println("-------------查询用户名为yellowcong的数据-------------");            //精确查询,根据名称来直接            Query query = parser.parse("username:yellowcong");            // 1.格式化对象,设置前缀和后缀            SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='red'>","</font>");            // 2.关键词对象(是highlight 的包)            Scorer scorer = new QueryScorer(query);            // 3. 高亮对象            Highlighter highlighter = new Highlighter(formatter, scorer);            IndexSearcher searcher = new IndexSearcher(reader);            TopDocs topDocs =searcher.search(query, 100);            System.out.println("查询到的条数\t"+topDocs.totalHits);            for(ScoreDoc score :topDocs.scoreDocs){                Document doc = reader.document(score.doc);                //给关键字添加高亮                String result = highlighter.getBestFragment(                        new StandardAnalyzer(Version.LUCENE_45),                         "username", //字段                        doc.get("username")); //高亮内容                System.out.println(result);            }            coloseReader(reader);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            coloseReader(reader);        }    }    private static QueryParser getQueryParser(){        QueryParser parser =new QueryParser(Version.LUCENE_45,"content", new StandardAnalyzer(Version.LUCENE_45));        return parser;    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月3日<br/>     * 创建时间:上午11:52:52<br/>     * 机能概要:关闭IndexReader     * @param reader     */    private static void coloseReader(IndexReader reader) {        try {            if (reader != null) {                reader.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    static {        psgList = new ArrayList<Passage>();        // 产生一堆数据        psgList.add(new Passage(1, "yellowcong一号" ,                "717350389@qq.com", "逗比", 23 , "I LOVE YOU ", new Date()));        psgList.add(new Passage(2, "张三yellowcong" ,                "zhashang@qq.com", "逗比", 23, "三炮", new Date()));        psgList.add(new Passage(3, "李四" ,                "lisi@neusoft.com", "逗比", 23, "三炮", new Date()));        psgList.add(new Passage(4, "王五" ,                "wangwu@aliyun.com", "逗比", 23, "三炮", new Date()));        psgList.add(new Passage(5, "赵yellowcong六" ,                "zhaoliu@baidu.com", "逗比", 23, "三炮", new Date()));        System.out.println("-------------------------添加的数据----------------------");        for(Passage psg:psgList){            System.out.println(psg.getId()+":"+psg.getUsername()+":"+psg.getEmail()+":"+psg.getContent());        }    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午5:43:57<br/>     * 机能概要:获取IndexWriter 同一时间 ,只能打开一个 IndexWriter,独占写锁 。内建线程安全机制。     *      * @return     * @throws Exception     */    @SuppressWarnings("static-access")    public static IndexWriter getIndexWriter() throws Exception {        // 创建IdnexWriter        String path = getIndexPath();        FSDirectory fs = FSDirectory.open(new File(path));        // 判断资源是否占用        if (writer == null || !writer.isLocked(fs)) {            synchronized (Demo3.class) {                if (writer == null || !writer.isLocked(fs)) {                    // 创建writer对象                    writer = new IndexWriter(fs,                            new IndexWriterConfig(Version.LUCENE_45, new StandardAnalyzer(Version.LUCENE_45)));                }            }        }        return writer;    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午5:46:36<br/>     * 机能概要:获取到IndexReader 任意多个IndexReaders可同时打开,可以跨JVM。     *      * @return     * @throws Exception     */    public static IndexReader getIndexReader() throws Exception {        // 创建IdnexWriter        String path = getIndexPath();        FSDirectory fs = FSDirectory.open(new File(path));        // 获取到读        return IndexReader.open(fs);    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午7:57:04<br/>     * 机能概要:删除所有的索引     */    public static void deleteAll() {        IndexWriter writer = null;        try {            // 获取IndexWriter            writer = getIndexWriter();            // 删除所有的数据            writer.deleteAll();            int cnt = writer.numDocs();            System.out.println("索引条数\t" + cnt);            // 提交事物            writer.commit();        } catch (Exception e) {            e.printStackTrace();        } finally {            coloseWriter(writer);        }    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午5:37:22<br/>     * 机能概要:获取索引目录     *      * @return 目录     */    private static String getIndexPath() {        // 获取索引的目录        String path = Demo3.class.getClassLoader().getResource("index").getPath();        // 不存在就创建目录        File file = new File(path);        if (!file.exists()) {            file.mkdirs();        }        return path;    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午8:24:16<br/>     * 机能概要:关闭IndexWriter     */    private static void coloseWriter(IndexWriter writer) {        try {            if (writer != null) {                writer.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午8:26:15<br/>     * 机能概要:关闭IndexReader     *      * @param reader     */    public static void closerReader(IndexReader reader) {        try {            if (reader != null) {                reader.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午8:10:01<br/>     * 机能概要: 查询数据     *      * @param key     *            查询范围     * @param val     *            值     */    public static void search(String key, Object val) {        IndexReader reader = null;        try {            reader = getIndexReader();            IndexSearcher searcher = new IndexSearcher(reader);            // 精确查询            Query query = null;            // 定义查询条件            if (val instanceof Integer) {                // 后面的两个true 表示的是 是否包含 上下的数据                query = NumericRangeQuery.newIntRange(key, Integer.parseInt(val.toString()),                        Integer.parseInt(val.toString()), true, true);            } else {                query = new TermQuery(new Term(key, val.toString()));            }            // QueryParser paraser = new QueryParser(Version.LUCENE_45, key, new            // StandardAnalyzer(Version.LUCENE_45));            // Query query = paraser.parse(val);            // 获取查询到的Docuemnt            TopDocs topDocs = searcher.search(query, 500);            // 总共命中的条数            System.out.println(topDocs.totalHits);            for (ScoreDoc score : topDocs.scoreDocs) {                //                Document doc = searcher.doc(score.doc);                // 查询到的结果                String username = doc.get("username");                System.out.println(username);            }        } catch (Exception e) {            e.printStackTrace();        } finally {            closerReader(reader);        }    }    /**     * 创建用户:狂飙的yellowcong<br/>     * 创建日期:2017年12月2日<br/>     * 创建时间:下午6:03:33<br/>     * 机能概要:建立索引     */    public static void index() {        IndexWriter writer = null;        try {            // 1、获取IndexWriter            writer = getIndexWriter();            // 2、建立索引            for (Passage psg : psgList) {                Document doc = new Document();                // IntField 不能直接检索到,需要结合                doc.add(new IntField("id", psg.getId(), Field.Store.YES));                // 用户String类型的字段的存储,StringField是只索引不分词                doc.add(new TextField("username", psg.getUsername(), Field.Store.YES));                // 主要对int类型的字段进行存储,需要注意的是如果需要对InfField进行排序使用SortField.Type.INT来比较,如果进范围查询或过滤,需要采用NumericRangeQuery.newIntRange()                doc.add(new IntField("age", psg.getAge(), Field.Store.YES));                // 对String类型的字段进行存储,TextField和StringField的不同是TextField既索引又分词                doc.add(new TextField("content", psg.getContent(), Field.Store.NO));                doc.add(new StringField("keyword", psg.getKeyword(), Field.Store.YES));                doc.add(new StringField("email", psg.getEmail(), Field.Store.YES));                // 日期数据添加索引                doc.add(new LongField("addDate", psg.getAddDate().getTime(), Field.Store.YES));                // 3、添加文档                writer.addDocument(doc);            }            // 索引条数            int cnt = writer.numDocs();            System.out.println("索引条数\t" + cnt);            // 提交事物            writer.commit();        } catch (Exception e) {            e.printStackTrace();        } finally {            coloseWriter(writer);        }    }    static class Passage {        private int id;        private String username;        private String email;        private String keyword;        private int age;        // 这个模拟的是文章        private String content;        private Date addDate;        public Passage(int id, String username, String email, String keyword, int age, String content, Date addDate) {            super();            this.id = id;            this.username = username;            this.email = email;            this.keyword = keyword;            this.age = age;            this.content = content;            this.addDate = addDate;        }        public int getId() {            return id;        }        public void setId(int id) {            this.id = id;        }        public String getUsername() {            return username;        }        public void setUsername(String username) {            this.username = username;        }        public String getEmail() {            return email;        }        public void setEmail(String email) {            this.email = email;        }        public String getKeyword() {            return keyword;        }        public void setKeyword(String keyword) {            this.keyword = keyword;        }        public int getAge() {            return age;        }        public void setAge(int age) {            this.age = age;        }        public String getContent() {            return content;        }        public void setContent(String content) {            this.content = content;        }        public Date getAddDate() {            return addDate;        }        public void setAddDate(Date addDate) {            this.addDate = addDate;        }    }}

参考文章

http://blog.csdn.net/rocky_03/article/details/69666445
http://blog.csdn.net/wuyinggui10000/article/details/45898099

原创粉丝点击