`

二十七、Luence在项目中运用

 
阅读更多

public class LuceneContext {


    private static LuceneContext instance;
    private static final String INDEX_PATH = "d:/lucene/test";
    private static IndexWriter writer;
    private static Analyzer analyzer;
    private static Version version;
    private static NRTManager nrtMgr;
    private static SearcherManager mgr;
    private static Directory directory;
    private LuceneContext(){}
   
    public static LuceneContext getInstance() {
        if(instance==null){
            System.out.println("init");
            init();
            instance = new LuceneContext();
        }
        return instance;
    }
   
    private static void init() {
        try {
            directory = FSDirectory.open(new File(INDEX_PATH));
            version = Version.LUCENE_35;
            String dicUrl = LuceneContext.class.getClassLoader().getResource("data").getPath();
            analyzer = new MMSegAnalyzer(dicUrl);
            writer = new IndexWriter(directory,new IndexWriterConfig(version,analyzer));
            nrtMgr = new NRTManager(writer, new SearcherWarmer() {
                @Override
                public void warm(IndexSearcher arg0) throws IOException {
                    System.out.println("reopen index");
                }
            });
            mgr = nrtMgr.getSearcherManager(true);
           
            NRTManagerReopenThread reopenThread = new NRTManagerReopenThread(nrtMgr, 5.0,0.025);
            reopenThread.setName("NRTManager reopen thread");
            reopenThread.setDaemon(true);
            reopenThread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    public IndexSearcher getSearcher() {
        return mgr.acquire();
    }
   
    public void releaseSearcher(IndexSearcher searcher) {
        try {
            mgr.release(searcher);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    public void commitIndex() {
        try {
            writer.commit();
            writer.forceMerge(3);
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    public NRTManager getNRTManager() {
        return nrtMgr;
    }
   
    public Version getVersion() {
        return version;
    }
   
    public Analyzer getAnalyzer() {
        return analyzer;
    }
}



public class IndexField {


    private String id;
    private String title;
    private List<String> content;
    private List<String> atths;
    private int parentId;
    private int objId;
    private Date createDate;
    private String type;


public class Index {
   
    private int msgId;
    private String title;
    private String summary;
    private Date createDate;


@Entity
@Table(name="temp_index")
public class TempIndex {
   
    private int id;
    private int objId;
    private String type;//Message,Attachment
    private int operator;



@Service("indexService")
public class IndexService implements IIndexService {



    private Document field2Doc(IndexField field) {
        Document doc = new Document();
        doc.add(new Field("id",field.getId(),Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
        doc.add(new Field("title",field.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
        for(String content:field.getContent()) {
            doc.add(new Field("content",content,Field.Store.NO,Field.Index.ANALYZED));
        }
        if(field.getAtths()!=null) {
            for(String att:field.getAtths()) {
                doc.add(new Field("atts",att,Field.Store.YES,Field.Index.NO));
            }
        }
        doc.add(new NumericField("objId",Field.Store.YES,true).setIntValue(field.getObjId()));
        doc.add(new NumericField("createDate",Field.Store.YES,true).setLongValue(field.getCreateDate().getTime()));
        return doc;
    }


    @Override
    public void addIndex(IndexField fields,boolean inDatabase) {
        try {
            if(inDatabase) {
                TempIndex ti = new TempIndex();
                ti.setAdd();
                ti.setObjId(fields.getObjId());
                ti.setType(fields.getType());
                tempIndexDao.add(ti);
            }
            NRTManager nrtMgr = LuceneContext.getInstance().getNRTManager();
            Document doc = field2Doc(fields);
            nrtMgr.addDocument(doc);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void deleteIndex(String id,String type) {
        try {
            TempIndex ti = new TempIndex();
            ti.setDelete();
            ///xx_xx
            ti.setId(Integer.parseInt(id));
            ti.setType(type);
            tempIndexDao.add(ti);
            LuceneContext.getInstance().getNRTManager().deleteDocuments(new Term("id",id));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void updateIndex(IndexField fields) {
        try {
            TempIndex ti = new TempIndex();
            ti.setDelete();
            ///xx_xx
            ti.setId(fields.getObjId());
            ti.setType(fields.getType());
            tempIndexDao.add(ti);
            NRTManager nrtMgr = LuceneContext.getInstance().getNRTManager();
            Document doc = field2Doc(fields);
            nrtMgr.updateDocument(new Term("id",fields.getId()), doc);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private String highligher(String text,Query query,String field) {
        try {
            QueryScorer scorer = new QueryScorer(query);
            Fragmenter fragmenter = new SimpleSpanFragmenter(scorer);
            Formatter formatter = new SimpleHTMLFormatter("<span class='lighter'>","</span>");
            Highlighter lighter = new Highlighter(formatter,scorer);
            lighter.setTextFragmenter(fragmenter);
            String ht = lighter.getBestFragment(LuceneContext.getInstance().getAnalyzer(),
                    field,text);
            if(ht==null) {
                if(text.length()>=200) {
                    text = text.substring(0, 200);
                    text=text+"....";
                }
                return text;
            }
            else return ht.trim();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidTokenOffsetsException e) {
            e.printStackTrace();
        }
        return text;
    }


    private ScoreDoc getLastDoc(int pageOffset,IndexSearcher searcher,Query query) {
        if(pageOffset<=0) return null;
        try {
            TopDocs tds = searcher.search(query,pageOffset-1);
            return tds.scoreDocs[pageOffset-1];
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public PageObject<Index> findByIndex(String condition) {
        if(condition==null) condition = "";
        IndexSearcher searcher = LuceneContext.getInstance().getSearcher();
        PageObject<Index> pages = new PageObject<Index>();
        List<Index> datas = new ArrayList<Index>();
        try {
            int pageSize = SystemContext.getPageSize();
            int pageOffset = SystemContext.getPageOffset();
            MultiFieldQueryParser parser = new MultiFieldQueryParser(LuceneContext.getInstance().getVersion(),
                        new String[]{"title","content"}, LuceneContext.getInstance().getAnalyzer());
            Query query = parser.parse(condition);
            TopDocs tds = searcher.searchAfter(getLastDoc(pageOffset,searcher,query),
                          query, pageSize);
            int totalRecord = tds.totalHits;
            List<Integer> msgs = new ArrayList<Integer>();
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                Index index = new Index();
                index.setCreateDate(new Date(Long.parseLong(doc.get("createDate"))));
                String title = doc.get("title");
                index.setTitle(highligher(title,query,"title"));
                String[] ans = doc.getValues("atts");
                StringBuffer content = new StringBuffer();
                if(ans!=null) {
                    for(String fn:ans) {
                        content.append(IndexUtil.file2String(fn));
                    }
                }
                index.setSummary(content.toString());
                int msgId = Integer.parseInt(doc.get("id"));
                index.setMsgId(msgId);
                msgs.add(msgId);
                datas.add(index);
            }
            Map<Integer,String> contents = messageDao.listMessageContent(msgs);
            for(int i=0;i<datas.size();i++) {
                Index index = datas.get(i);
                String content = contents.get(index.getMsgId());
                content = content+index.getSummary();
                datas.get(i).setSummary(highligher(content,query,"content"));
            }
           
            pages.setDatas(datas);
            pages.setOffset(pageOffset);
            pages.setPageSize(pageSize);
            pages.setTotalRecord(totalRecord);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TikaException e) {
            e.printStackTrace();
        } finally {
            LuceneContext.getInstance().releaseSearcher(searcher);
        }
        return pages;
    }


    private void indexMessage(Message msg) {
        List<String> contents = new ArrayList<String>();
        List<String> ans = new ArrayList<String>();
        contents.add(msg.getContent());
        List<Attachment> atts = attachmentDao.listByMessage(msg.getId());
        for(Attachment att:atts) {
            IndexUtil.attach2Index(contents, ans,att);
        }
        IndexField field = IndexUtil.msg2IndexField(msg);
        field.setContent(contents);
        field.setAtths(ans);
        addIndex(field,false);
    }


    private void indexMessages(List<Message> messages) {
        for(Message msg:messages) {
            indexMessage(msg);
        }
    }


    @Override
    public void updateReconstructorIndex() {
        /**
         * 将数据库中的所有对象取出,创建相应的IndexField完成索引的重构
         */
        try {
            LuceneContext.getInstance().getNRTManager().deleteAll();
            List<Message> messages = messageDao.list("from Message");
            indexMessages(messages);
            LuceneContext.getInstance().commitIndex();
            tempIndexDao.delAll();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void updateSetIndex() {
        List<TempIndex> tis = tempIndexDao.list("from TempIndex");
        for(TempIndex ti:tis) {
            if(ti.getType().equals(IndexUtil.MSG_TYPE)) {
                Message msg = messageDao.load(ti.getObjId());
                indexMessage(msg);
            }
        }
        LuceneContext.getInstance().commitIndex();
        tempIndexDao.delAll();
    }


    @Override
    public void updateCommitIndex() {
        tempIndexDao.delAll();
        LuceneContext.getInstance().commitIndex();
    }

}


public class CleanListener implements ServletContextListener {

    private Timer indexTimer;

    private WebApplicationContext wac = null;


    private class IndexCommit extends TimerTask {
        @Override
        public void run() {
            SystemContext.setRealPath(realPath);
            System.out.println("索引进行了提交"+new Date());
            IIndexService indexService = (IIndexService)wac.getBean("indexService");
            indexService.updateCommitIndex();
        }
    }


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //可以获取spring中BeanFactory,这个BeanFactory是在系统启动的时候就完成存储了
        wac = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
        System.out.println("------------------清理的启动程序已经开启(已经获取了"+wac+")---------------------");
        realPath = sce.getServletContext().getRealPath("");
        timer = new Timer();
        timer.scheduleAtFixedRate(new ClearDataTask(),50000, 300000);
        indexTimer = new Timer();
        indexTimer.scheduleAtFixedRate(new IndexCommit(), 600000, 600000);
    }


分享到:
评论

相关推荐

    luence客户端测试软件luke

    5. **应用场景**:Luke在Lucene开发过程中用于调试和验证搜索逻辑,也可用于诊断搜索性能问题,或者在生产环境中作为日常监控和维护工具。 6. **版本更新**:"03-luke"可能代表一个特定版本,随着Lucene的更新,...

    Luence.net搜索小程序

    在搜索高亮方面,Luence.net提供了一种有效的方法,可以将用户的查询关键字在搜索结果中突出显示,增强用户体验。这通常通过分析搜索结果文档,找出匹配的关键词,并用特定的样式(如加粗、颜色变化等)进行标记来...

    Luence in Action 中英文pdf 版

    8. **实战案例**:书中包含多个实际项目案例,帮助读者将理论知识转化为实践,包括构建搜索引擎、日志分析和内容管理系统等。 9. **Lucene最新版本特性**:英文版可能会包含Lucene的最新版本特性,比如新的API、...

    Luence和ElasticSearch面试准备.docx

    《Luence和ElasticSearch面试准备》 Lucene和ElasticSearch是两个在全文搜索引擎领域中广泛使用的开源工具。Lucene是一个高性能、全文本搜索库,而Elasticsearch则是在Lucene的基础上构建的一个分布式、RESTful风格...

    Luence搜索Demo

    Lucene最初是用Java编写的,但随着.NET生态的发展,Luence.Net应运而生,为.NET开发者提供了一种在C#或VB.NET环境中构建全文检索应用的便捷途径。 在"Luence.Net搜索Demo"中,我们可以学习到以下几个关键知识点: ...

    Luence原理及源码分析

    lucene 原理与分析,底层源码解析,应用场景及实践,相关配置

    IKAnalyzer和luence压缩包大全

    IKAnalyzer和Lucene是两个在中文处理领域广泛应用的开源项目。IKAnalyzer是一个专门针对中文的分词工具,而Lucene则是一个全文检索框架。这里我们深入探讨这两个组件以及它们的关联。 **IKAnalyzer** 是一个高性能...

    获取全部Luence数据

    ### 获取全部Luence数据 #### 知识点详解 **Lucene** 是一个高性能、全功能的文本搜索引擎库。在本文档中,我们将探讨如何通过Lucene获取索引中的所有文档,包括创建索引、查询索引以及遍历所有文档的具体步骤。 ...

    Luence的与盘古分词的使用软件

    在项目中,开发者可能创建一个类或模块来处理分词逻辑,通过调用盘古分词的API将用户输入的句子进行分词,得到词汇列表。然后,这些词汇可能被用来在Lucene构建的索引中进行查询,以找到相关的数据。 具体步骤可能...

    luence索引例子

    标题 "luence索引例子" 暗示我们要探讨的是Lucene,一个广泛使用的全文搜索引擎库,它在处理大量文本数据时提供了高效的检索能力。在这个例子中,我们将深入理解如何利用Lucene创建索引来优化数据库记录的搜索性能。...

    Luence简单实例

    在"Luence简单实例"中,我们可能会看到以下步骤的Java代码实现: 1. **创建索引**: 首先,需要创建一个`IndexWriter`对象,设置好索引目录和分析器。接着,通过`Document`对象添加字段,如`add(new Field("content...

    luence搜索

    在实际项目中,通常会结合数据库来使用Lucene。首先,从数据库读取数据,然后构建Lucene文档并建立索引。当数据库中的数据发生变化时,需要同步更新Lucene索引,确保搜索结果的准确性。此外,还可以通过优化索引策略...

    luence4.6例子

    《Apache Lucene 4.6源代码解析》 Apache Lucene 是一个开源的全文检索库,由Java编写,为开发者提供...此外,还可以了解到软件设计模式、数据结构和算法在实际项目中的应用,对于提升Java开发者的技能水平大有裨益。

    Luence+Ikanalyzer+stopword+dic

    在Lucene中,为了提高搜索的准确性和效率,通常会使用到一些优化技术,如分词器(Analyzer)和停用词表(Stopword List)。Ikanalyzer是专门为中文处理设计的一个分词器,而stopword+dic则涉及到如何定制和使用...

    前后端分离项目使用的spring Mvc、 mybatis、 luence、 spring 开发的开源知识库系统的所有后端端源码.zip

    前后端分离项目使用的spring Mvc、 mybatis、 luence、 spring 开发的开源知识库系统的所有后端端源码。 下载可运行。 使用前后端分离架构, 使用springMvc 、 spring、 mybatis、 luence等技术开发的开源知识库所有...

    前后端分离的使用spring Mvc、 mybatis、 luence、 spring 开发的开源知识库系统的所有后端端源码

    在本项目中,Spring MVC作为后端的核心组件,负责接收前端请求,处理业务逻辑,与数据库交互,并返回响应数据。它的优点包括依赖注入、面向切面编程以及强大的异常处理能力。 接着,MyBatis是一个轻量级的持久层...

    人工智能-项目实践-搜索引擎-基本的垂直搜索引擎,实现了基本的网络爬虫功能以及用Luence实现检索

    在这个项目中,我们实现了一个基础的网络爬虫,用于抓取特定领域内的网页内容。 2. **爬虫架构**:通常,一个简单的爬虫包括URL管理器、下载器和解析器三个主要部分。URL管理器负责跟踪待抓取的URL队列,下载器则将...

    lucene索引与搜索(含jar包)

    **Lucene 索引与搜索** Lucene 是一个由 Apache 软件基金会开发的全文检索库,它提供了一个高性能、可扩展的信息检索服务...在实际项目中,可以根据业务需求对这些基本组件进行调整和优化,以提高搜索性能和用户体验。

    VerticalSearcher:基本的垂直搜索引擎,实现了基本的网络爬虫功能以及用Luence实现检索

    在这个项目中,爬虫部分主要负责从指定的URL起点出发,按照一定的规则(如深度优先或广度优先)遍历网页,提取出有价值的数据。这些数据可能包括文本内容、链接、图片等,然后存储到本地数据库或文件系统中,供后续...

    毕设项目-基于SpringBoot+mybatis搜索引擎优化的健康问答系统java源码+项目说明.7z

    毕设项目 基于SpringBoot+mybatis搜索引擎优化的健康问答系统系统java源码+项目说明.7z 采用spring boot + mybatis 框架构建 前端模型采用 theleaf 模板 ...ask-util: 工具模块,存放项目中各种共用的工具类

Global site tag (gtag.js) - Google Analytics