从Web模块调用时,为什么Lucene IndexWriter没有更新索引? [英] Why did Lucene IndexWriter did not update the index when called from a Web Module?

查看:73
本文介绍了从Web模块调用时,为什么Lucene IndexWriter没有更新索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对使用Lucene的Web项目有一个奇怪的问题. 我已经编写了一个将业务对象的数据写入Lucene的bean.业务数据由Web前端提供.这一切都很好. 但是在极少数情况下,业务对象不会添加到索引中.似乎在多个用户访问Bean的情况下会发生这种情况.

I have a strange problem with a Web Project using Lucene. I have written a bean which writes the data of a business object into Lucene. The business data is provided by the web front end. This all works very fine. But in some rarely cases the business object is not added into the index. It seems that this happens in cases when multiple users are accessing the bean.

我的bean使用静态方法创建Lucene IndexWriter并在我的业务对象的基础上创建Lucene Document. 我认为使所有方法静态化就足以节省线程.但是现在我想知道是否有必要使我的更新方法也同步"以避免与其他线程发生冲突? 在没有将对象写入索引的情况下,lucene不会引发任何异常.所以我不能说在我的图层后面会发生什么.

My bean uses static methods creating the Lucene IndexWriter and creating a Lucene Document on base of my business object. I thought making all methods static is enough to become thread save. But now I wonder if it is necessary to make my update method also 'synchronized' to avoid conflicts with other threads? In the cases when the object is not written into the index there are no exceptions thrown from lucene. So I can not say what happens behind my layer.

我的更新方法如下:

public static boolean updateWorklist(ItemCollection workitem) throws PluginException {

        IndexWriter awriter = null;
        // try loading imixs-search properties
        Properties prop = loadProperties();
        if (prop.isEmpty())
            return false;

        try {
            awriter = createIndexWriter(prop);

            // create term
            Term term = new Term("$uniqueid", workitem.getItemValueString("$uniqueid"));
            // test if document should be indexed or not
            if (matchConditions(prop, workitem)) {
                logger.fine("add workitem '" + workitem.getItemValueString(EntityService.UNIQUEID) + "' into index");
                awriter.updateDocument(term, createDocument(workitem));
            } else {
                logger.fine("remove workitem '" + workitem.getItemValueString(EntityService.UNIQUEID) + "' into index");
                awriter.deleteDocuments(term);
            }
        } catch (IOException luceneEx) {
            // close writer!
            logger.warning(" Lucene Exception : " + luceneEx.getMessage());

            throw new PluginException(LucenePlugin.class.getSimpleName(), INVALID_INDEX,
                    "Unable to update search index", luceneEx);

        } finally {

            if (awriter != null) {
                logger.fine(" close writer");
                try {
                    awriter.close();
                } catch (CorruptIndexException e) {
                    throw new PluginException(LucenePlugin.class.getSimpleName(), INVALID_INDEX,
                            "Unable to update search index", e);
                } catch (IOException e) {
                    throw new PluginException(LucenePlugin.class.getSimpleName(), INVALID_INDEX,
                            "Unable to update search index", e);
                }

            }
        }

        logger.fine(" update worklist successfull");
        return true;
    }

.....

    public static IndexWriter createIndexWriter(Properties prop)
            throws IOException {

        /**
         * Read configuration
         */
        // String sLuceneVersion = prop.getProperty("Version", "LUCENE_45");

        String sIndexDir = prop.getProperty("lucence.indexDir");
        String sFulltextFieldList = prop
                .getProperty("lucence.fulltextFieldList");
        String sIndexFieldListAnalyse = prop
                .getProperty("lucence.indexFieldListAnalyze");
        String sIndexFieldListNoAnalyse = prop
                .getProperty("lucence.indexFieldListNoAnalyze");

        logger.fine("IndexDir:" + sIndexDir);
        logger.fine("FulltextFieldList:" + sFulltextFieldList);
        logger.fine("IndexFieldListAnalyse:" + sIndexFieldListAnalyse);
        logger.fine("IndexFieldListNoAnalyse:" + sIndexFieldListNoAnalyse);
        // compute search field list
        StringTokenizer st = new StringTokenizer(sFulltextFieldList, ",");
        searchFieldList = new ArrayList<String>();
        while (st.hasMoreElements()) {
            String sName = st.nextToken().toLowerCase();
            // do not add internal fields
            if (!"$uniqueid".equals(sName) && !"$readaccess".equals(sName))
                searchFieldList.add(sName);
        }

        // compute Index field list (Analyze)
        st = new StringTokenizer(sIndexFieldListAnalyse, ",");
        indexFieldListAnalyse = new ArrayList<String>();
        while (st.hasMoreElements()) {
            String sName = st.nextToken().toLowerCase();
            // do not add internal fields
            if (!"$uniqueid".equals(sName) && !"$readaccess".equals(sName))
                indexFieldListAnalyse.add(sName);
        }

        // compute Index field list (Analyze)
        st = new StringTokenizer(sIndexFieldListNoAnalyse, ",");
        indexFieldListNoAnalyse = new ArrayList<String>();
        while (st.hasMoreElements()) {
            String sName = st.nextToken().toLowerCase();
            // do not add internal fields
            if (!"$uniqueid".equals(sName) && !"$readaccess".equals(sName))
                indexFieldListNoAnalyse.add(sName);
        }

        /**
         * Now create a IndexWriter Instance
         */
        Directory indexDir = createIndexDirectory(prop);

        Analyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
                Version.LATEST, analyzer);

        // set the WriteLockTimeout to wait for a write lock (in milliseconds)
        // for this instance. 10 seconds!
        indexWriterConfig.setWriteLockTimeout(10000);

        return new IndexWriter(indexDir, indexWriterConfig);
    }

....

public static boolean matchConditions(Properties prop, ItemCollection aworktiem) {

    String typePattern = prop.getProperty("lucence.matchingType");
    String processIDPattern = prop.getProperty("lucence.matchingProcessID");

    String type = aworktiem.getItemValueString("Type");
    String sPid = aworktiem.getItemValueInteger("$Processid") + "";

    // test type pattern
    if (typePattern != null && !"".equals(typePattern) && !type.matches(typePattern)) {
        logger.fine("Lucene type '" + type + "' did not match pattern '" + typePattern + "'");
        return false;
    }

    // test $processid pattern
    if (processIDPattern != null && !"".equals(processIDPattern) && !sPid.matches(processIDPattern)) {
        logger.fine("Lucene $processid '" + sPid + "' did not match pattern '" + processIDPattern + "'");

        return false;
    }
    return true;
}

.... 编辑20月1日: 我在代码示例中添加了IndexWriter方法.我的属性文件为空,没有为IndexWriter提供任何Lucene设置

.... Edit 20.Jan: I added the IndexWriter method into the code example. My property file is empty and did not provide any lucene settings to the IndexWriter

编辑21月1日: 我添加了matchConditions方法

Edit 21.Jan: I added the matchConditions method

推荐答案

如@ maksim07所述,我实现中的问题是使用静态变量和方法.因此,由于存在竞争条件,因此createDocument方法可以观察到空的searchFieldList,indexFieldListAnalyse和indexFieldListNoAnalyse集合.

As explained by @maksim07, the problem in my implementation was the use of static variables and methods. So the createDocument method could observe empty searchFieldList, indexFieldListAnalyse, indexFieldListNoAnalyse collections since there was a race condition.

最后,我通过使用单独的init()方法使用单例模式来重新实现代码,在该方法中,我初始化了成员变量的所有值. 使用Singleton EJB使得使用Singleton模式非常容易,并且可以确保所有方法调用都通过EJB容器的默认行为进行同步.

Finally I re-implemented the code by using the singleton pattern with a separate init() method where I initialized all the values of my member variables. Using a Singleton EJB makes the usage of a singleton pattern very easy and guaranties that all method calls are synchronized by the default behavior of the EJB container.

这篇关于从Web模块调用时,为什么Lucene IndexWriter没有更新索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆