我正在尝试在具有多个线程的Lucene中建立索引。因此,我开始编码并编写以下代码。首先,找到文件,然后为每个文件创建一个线程以对其进行索引。之后,我加入线程并优化索引。它可以工作,但我不确定…我可以大规模信任它吗?有什么办法可以改善吗?
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Document;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.apache.lucene.index.TermFreqVector;
public class mIndexer extends Thread {
private File ifile;
private static IndexWriter writer;
public mIndexer(File f) {
ifile = f.getAbsoluteFile();
}
public static void main(String args[]) throws Exception {
System.out.println("here...");
String indexDir;
String dataDir;
if (args.length != 2) {
dataDir = new String("/home/omid/Ranking/docs/");
indexDir = new String("/home/omid/Ranking/indexes/");
}
else {
dataDir = args[0];
indexDir = args[1];
}
long start = System.currentTimeMillis();
Directory dir = FSDirectory.open(new File(indexDir));
writer = new IndexWriter(dir,
new StopAnalyzer(Version.LUCENE_34, new File("/home/omid/Desktop/stopwords.txt")),
true,
IndexWriter.MaxFieldLength.UNLIMITED);
int numIndexed = 0;
try {
numIndexed = index(dataDir, new TextFilesFilter());
} finally {
long end = System.currentTimeMillis();
System.out.println("Indexing " + numIndexed + " files took " + (end - start) + " milliseconds");
writer.optimize();
System.out.println("Optimization took place in " + (System.currentTimeMillis() - end) + " milliseconds");
writer.close();
}
System.out.println("Enjoy your day/night");
}
public static int index(String dataDir, FileFilter filter) throws Exception {
File[] dires = new File(dataDir).listFiles();
for (File d: dires) {
if (d.isDirectory()) {
File[] files = new File(d.getAbsolutePath()).listFiles();
for (File f: files) {
if (!f.isDirectory() &&
!f.isHidden() &&
f.exists() &&
f.canRead() &&
(filter == null || filter.accept(f))) {
Thread t = new mIndexer(f);
t.start();
t.join();
}
}
}
}
return writer.numDocs();
}
private static class TextFilesFilter implements FileFilter {
public boolean accept(File path) {
return path.getName().toLowerCase().endsWith(".txt");
}
}
protected Document getDocument() throws Exception {
Document doc = new Document();
if (ifile.exists()) {
doc.add(new Field("contents", new FileReader(ifile), Field.TermVector.YES));
doc.add(new Field("path", ifile.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
String cat = "WIR";
cat = ifile.getAbsolutePath().substring(0, ifile.getAbsolutePath().length()-ifile.getName().length()-1);
cat = cat.substring(cat.lastIndexOf('/')+1, cat.length());
//doc.add(new Field("category", cat.subSequence(0, cat.length()), Field.Store.YES));
//System.out.println(cat.subSequence(0, cat.length()));
}
return doc;
}
public void run() {
try {
System.out.println("Indexing " + ifile.getAbsolutePath());
Document doc = getDocument();
writer.addDocument(doc);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
任何麻将被视为。
如果要并行化索引,可以执行以下两项操作:
您可以并行处理对addDocuments的调用,但是随着需要索引的文档数量的增加,每个文档产生一个线程将无法扩展。您应该使用固定大小的ThreadPoolExecutor。由于此任务主要是CPU密集型(取决于分析仪和检索数据的方式),因此将计算机的CPU数量设置为最大线程数可能是一个不错的开始。
关于合并调度程序,您可以增加可与ConcurrentMergeScheduler的setMaxThreadCount方法一起使用的最大线程数。请注意,磁盘在顺序读取/写入方面比随机读取/写入要好得多,因此,为合并调度程序设置的最大最大线程数可能会降低索引编制的速度,而不是加快索引编制的速度。
但是在尝试并行化索引过程之前,您可能应该尝试找到瓶颈所在。如果磁盘速度太慢,则可能是刷新的瓶颈,因此合并步骤将导致并行调用addDocument(本质上包括分析文档并将分析结果缓存在内存中)不会提高索引速度完全没有
一些注意事项:
Lucene的开发版本中正在进行一些工作,以改善索引并行性(尤其是冲洗部分,此博客文章解释了其工作原理)。
Lucene在如何提高索引速度方面有一个不错的Wiki页面,您将找到其他提高索引速度的方法。
我有一个多步骤Spring Batch作业,在其中一个步骤中,我为在阅读器中读取的数据创建Lucene索引,以便后续步骤可以在该Lucene索引中搜索。 基于中读取的数据,我将索引分散到几个单独的目录中。 如果我指定Step Task Executor为,只要索引总是写入不同的目录,我就不会遇到任何问题,但有时会出现锁定异常。我猜,两个线程试图写入同一个索引。 如果我删除了,我不会遇到任何问题,但
我在建立一个简单的地址数据库。有一个名为的类,其中的地址被分解为字段(street、city、state、ZIP)。每个字段都是字符串类型。 我想能够搜索地址中的任何一个字。例如:查找地址,无论搜索的词是在街道名称或城市名称等。换句话说,我希望用户能够轻松搜索,而不必指定他们感兴趣的地址的哪一部分。 但是当我执行以下查询时,我不会得到结果或错误消息: =>没有结果,应该是2条邮政编码为46250和
4.2.2 用函数改善程序结构 上一节讨论了函数的减少重复代码、精简程序的作用,并利用函数的这个功能将程序 4.1 改进成了程序 4.2。在该节的最后,我们也给出了一个不宜用函数来减少重复代码的情况。 还能不能利用函数将程序 4.2 变得更好呢? 我们在 4.1 节中一般地讨论了模块化编程,在 Python 中,函数就是用于模块化编程的 重要工具。当算法很复杂时,程序就会变得难以理解。据说人类擅长
通过对 manifest.json 进行相应配置,可以提升 PWA 从主屏幕启动时的应用体验。 添加启动画面 设置显示类型 指定显示方向 设置主题色 添加启动画面 当 PWA 从主屏幕点击打开时,幕后执行了若干操作: 启动浏览器 启动显示页面的渲染器 加载资源 在这个过程中,由于页面未加载完毕,因此屏幕将显示空白并且看似停滞。如果是从网络加载的页面资源,白屏过程将会变得更加明显。因此 PWA 提供
我想索引和搜索使用Lucene索引的数据片段。 例如。物品及其颜色 搜索示例 可能的解决办法 根据我在答案中发现的,显然我可以使用这种格式将这些添加到一个字段中。 如果我现在用这种格式的数据进行搜索,我不会得到任何结果。 null
我可以使用Lucene查询ElasticSearch索引吗? 我使用ElasticSearch创建了一个索引,并插入了以下三个文档: null 不幸的是,d.get(“_source”)也返回null。 如何检索匹配查询的文档字段? 谢谢你。