Java,Lucene:在Java中为IndexWriter设置锁定超时.

我正在努力将Lucene与基于Spring-MVC的应用程序集成.目前我们有它工作,但很少我们得到一个无法获得锁定错误.之后我必须手动删除锁定文件然后才能正常工作.

如何设置在Java中锁定索引的超时?我没有Lucene的任何XML配置.我通过POM.xml在maven中添加了项目库,并实例化了所需的类.

代码:

public void saveIndexes(String text, String tagFileName, String filePath, long groupId, boolean type, int objectId) {
        try {
            // path is the indexing directory. 
            File testDir;
            Path suggestionsPath;
            Directory suggestionsDir;

            Path phraseSuggestPath;
            Directory phraseSuggestDir;

            Directory directory = org.apache.lucene.store.FSDirectory.open(path);
            IndexWriterConfig config = new IndexWriterConfig(new SimpleAnalyzer());
            IndexWriter indexWriter = new IndexWriter(directory, config);

            org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document();
            if (filePath != null) {
                File file = new File(filePath); // current directory
                doc.add(new TextField("path", file.getPath(), Field.Store.YES));
            }
            doc.add(new StringField("id", String.valueOf(objectId), Field.Store.YES));
            //  doc.add(new TextField("id",String.valueOf(objectId),Field.Store.YES));
            if (text == null) {
                if (filePath != null) {
                    FileInputStream is = new FileInputStream(filePath);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    StringBuilder stringBuffer = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        stringBuffer.append(line).append("\n");
                    }
                    stringBuffer.append("\n").append(tagFileName);
                    reader.close();
                    doc.add(new TextField("contents", stringBuffer.toString(), Field.Store.YES));
                }
            } else {

                FieldType fieldType = new FieldType(TextField.TYPE_STORED);
                fieldType.setTokenized(false);
                doc.add(new Field("contents", text+"\n"+tagFileName, fieldType));
            }
            indexWriter.addDocument(doc);
            indexWriter.commit();
            indexWriter.flush();
            indexWriter.close();
            directory.close();

            StandardAnalyzer analyzer = new StandardAnalyzer();
            AnalyzingInfixSuggester wordSuggester = new AnalyzingInfixSuggester(suggestionsDir, analyzer);

            ArrayList<String> words = new ArrayList<>();
            if (text != null) {
                text = html2text(text);
                Pattern pt = Pattern.compile("[^\\w\\s]");
                Matcher match = pt.matcher(text);
                while (match.find()) {
                    String s = match.group();
                    text = text.replaceAll("\\" + s, "");
                }

                if (text.contains(" ")) {
                    Collections.addAll(words, text.split(" "));

                } else {
                    words.add(text);
                }
                SuggestionIterator suggestionIterator = new SuggestionIterator(words.iterator());
                wordSuggester.build(suggestionIterator);
                wordSuggester.close();
                suggestionsDir.close();
            }

            AnalyzingInfixSuggester phraseSuggester = new AnalyzingInfixSuggester(phraseSuggestDir, analyzer);
            if (text != null) {
                text = html2text(text);
                ArrayList<String> phrases = new ArrayList<>();
                phrases.add(text);
                SuggestionIterator suggestionIterator = new SuggestionIterator(phrases.iterator());
                phraseSuggester.build(suggestionIterator);
                phraseSuggester.close();
                phraseSuggestDir.close();
            }

        } catch (Exception ignored) {
        }
    }

谢谢.

解决方法:

我引用了IndexWriter Documentation的两件事,

Opening an IndexWriter creates a lock file for the directory in use.
Trying to open another IndexWriter on the same directory will lead to
a LockObtainFailedException.

NOTE: IndexWriter instances are completely thread safe, meaning
multiple threads can call any of its methods, concurrently. If your
application requires external synchronization, you should not
synchronize on the IndexWriter instance as this may cause deadlock;
use your own (non-Lucene) objects instead.

因此,如果IndexWriter已经打开并且未在其他位置关闭,则无法再次打开它.在您的情况下,当两个用户处于相同的代码块时,恰好有一些不幸的时间.

您可以通过两种方式解决此问题,

1.设计关键部分:将编写器打开,使用和关闭操作的代码部分标记为关键部分,并在该关键部分应用Java同步.使用一些应用程序Singleton bean进行同步.因此,当另一个用户点击该块时,他将等到第一个用户完成并释放锁定.

2.Single Writer实例:在你的应用程序中开发一种机制,只在应用程序的生命周期内打开和关闭一次编写器,并将该单个实例传递给服务代码,这样编写器方法就可以被所需的用户调用,因为编写器实例是由Lucene人员制作线程安全的.
我想,这可以通过Singleton Spring bean并在您的服务中注入该bean来实现.

第二种方法的缺点是 – 单个全局索引目录的多服务器部署,以及是否有其他应用程序试图在该全局索引上打开编写器.这个问题可以通过将索引编写器实例创建代码包装在某种全局服务中来解决,该服务将相同的实例返回到尝试使用它的任何应用程序.

这不是您尝试通过删除锁定文件或引入超时来解决的简单问题.您必须根据IndexWriter文档建模您的设计,而不是其他方式.

单个编写器实例也将引入一些性能改进.

此外,在创建编写器后立即进行空提交练习.这帮助我解决了过去的一些问题.

上一篇:PHP找到相关性


下一篇:java – Lucene按URL搜索