除非数据库已经是您解决方案的一部分,否则我不会为您的解决方案增加额外的复杂性。引用 SOLR FAQ 是您的 servlet 容器发出会话超时。
在我看来,你有几个选择(按照我的偏好):
增加容器超时时间
增加容器超时时间。 (“maxIdleTime”参数,如果您使用的是嵌入式 Jetty 实例)。
我假设您只是偶尔索引这么大的文件?暂时增加超时可能只是最简单的选择。
拆分文件
这是一个简单的 unix 脚本,可以完成这项工作(将文件分成 500,000 行块):
split -d -l 500000 data.csv split_files.
for file in `ls split_files.*`
do
curl 'http://localhost:8983/solr/update/csv?fieldnames=id,name,category&commit=true' -H 'Content-type:text/plain; charset=utf-8' --data-binary @$file
done
解析文件并分块加载
以下 groovy 脚本使用 opencsv 和 solrj 解析 CSV 文件并每 500,000 行将更改提交到 Solr。
import au.com.bytecode.opencsv.CSVReader
import org.apache.solr.client.solrj.SolrServer
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer
import org.apache.solr.common.SolrInputDocument
@Grapes([
@Grab(group='net.sf.opencsv', module='opencsv', version='2.3'),
@Grab(group='org.apache.solr', module='solr-solrj', version='3.5.0'),
@Grab(group='ch.qos.logback', module='logback-classic', version='1.0.0'),
])
SolrServer server = new CommonsHttpSolrServer("http://localhost:8983/solr/");
new File("data.csv").withReader { reader ->
CSVReader csv = new CSVReader(reader)
String[] result
Integer count = 1
Integer chunkSize = 500000
while (result = csv.readNext()) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", result[0])
doc.addField("name_s", result[1])
doc.addField("category_s", result[2])
server.add(doc)
if (count.mod(chunkSize) == 0) {
server.commit()
}
count++
}
server.commit()
}