作为我的DSpace实例的一部分,我有一个包含1200万使用情况统计记录的SOLR存储库。某些记录已通过多个SOLR升级进行迁移,并且不符合当前架构。其中500万条记录缺少我的架构中指定的唯一ID字段。
DSpace系统提供了一种机制,可以使用以下代码将旧的使用情况统计记录分成单独的solr分片。
DSPACE SHARD LOGIC:
for (File tempCsv : filesToUpload) {
//Upload the data in the csv files to our new solr core
ContentStreamUpdateRequest contentStreamUpdateRequest = new ContentStreamUpdateRequest("/update/csv");
contentStreamUpdateRequest.setParam("stream.contentType", "text/plain;charset=utf-8");
contentStreamUpdateRequest.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
contentStreamUpdateRequest.addFile(tempCsv, "text/plain;charset=utf-8");
statisticsYearServer.request(contentStreamUpdateRequest);
}
statisticsYearServer.commit(true, true);
当我尝试运行此过程时,我收到了一条错误消息,指出我的每条记录都缺少唯一ID字段,并且该过程已删除了500万条记录。
我试图替换这500万条记录,以强制在每条记录上创建唯一的id字段。这是我正在运行以触发该更新的代码。查询myQuery迭代数千条记录的批次。
我的录音修复程序:
ArrayList<SolrInputDocument> idocs = new ArrayList<SolrInputDocument>();
SolrQuery sq = new SolrQuery();
sq.setQuery(myQuery);
sq.setRows(MAX);
sq.setSort("time", ORDER.asc);
QueryResponse resp = server.query(sq);
SolrDocumentList list = resp.getResults();
if (list.size() > 0) {
for(int i=0; i<list.size(); i++) {
SolrDocument doc = list.get(i);
SolrInputDocument idoc = ClientUtils.toSolrInputDocument(doc);
idocs.add(idoc);
}
}
server.add(idocs);
server.commit(true, true);
server.deleteByQuery(myQuery);
server.commit(true, true);
运行此过程后,存储库中的所有记录都会分配唯一的ID。我所触及的记录也有一个 _version _ 字段。
当我尝试重新运行上面包含的分片过程时,我收到与 _version _ 字段值相关的错误,并且该过程终止。如果我尝试显式设置版本字段,则会收到相同的错误。
以下是我在调用分片进程时遇到的错误消息:
Exception: version conflict for e8b7ba64-8c1e-4963-8bcb-f36b33216d69 expected=1484794833191043072 actual=-1
org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException: version conflict for e8b7ba64-8c1e-4963-8bcb-f36b33216d69 expected=1484794833191043072 actual=-1
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:424)
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:180)
我的目标是修复我的记录,以便我可以运行DSpace提供的分片过程。您能否建议我采取任何其他措施来修复这些记录?
答案 0 :(得分:1)
修改生成的csv应该更容易。
尝试在fs方法之前直接添加一个方法来为csv添加id。
FileUtils.copyInputStreamToFile(csvInputstream,csvFile);
//&lt; -a方法调用重新打开csv文件并添加的函数 每行的强制ID
filesToUpload.add(csvFile); //添加10000&amp;重新开始 yearQueryParams.put(CommonParams.START,String.valueOf((i + 10000))); }
for(File tempCsv:filesToUpload){
(...)
答案 1 :(得分:1)
SolrLogger中的分片代码将记录复制到一个新的空核心。问题是来自大约DSpace 3的DSpace使用情况统计文档包含_version_
字段,并且此字段在分片期间包含在副本中。
当包含_version_
字段的文档添加到Solr索引时,这会触发Solr的乐观并发功能,该功能会检查索引中具有相同唯一ID的现有文档。逻辑大致如下(见http://yonik.com/solr/optimistic-concurrency/):
_version_
&gt; 1:文档版本必须完全匹配_version_
= 1:文档必须存在_version_
&lt; 0:文档不得存在_version_
= 0:不关心(正常覆盖,如果存在)
包含_version_
值&gt;的使用情况统计文档因此,1使Solr在新创建的年份分片中查找具有相同唯一ID的现有文档;但是,显然当时没有这样的文件,因此版本冲突。
分片期间的复制过程会创建临时CSV文件,然后将其导入新核心。幸运的是,可以使用skip参数告诉Solr的CSV更新处理程序从导入中排除特定字段:https://wiki.apache.org/solr/UpdateCSV#skip
像这样更改分片代码
//Upload the data in the csv files to our new solr core
ContentStreamUpdateRequest contentStreamUpdateRequest = new ContentStreamUpdateRequest("/update/csv");
contentStreamUpdateRequest.setParam("stream.contentType", "text/plain;charset=utf-8");
+ contentStreamUpdateRequest.setParam("skip", "_version_");
contentStreamUpdateRequest.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
contentStreamUpdateRequest.addFile(tempCsv, "text/plain;charset=utf-8");
跳过_version_
字段,进而禁用乐观并发检查。
https://jira.duraspace.org/browse/DS-2212在https://github.com/DSpace/DSpace/pull/893处提出了拉取请求,对此进行了讨论;希望这将包含在DSpace 5.2中。
答案 2 :(得分:0)
我试图将1.8.3升级到4.2,包含400万条记录,所有记录都缺少uid和版本。我写了一个脚本来读取Solr(批量为10,000),重新写入副本,最后删除原件。结果看起来很好,直到我尝试分片,当我看到这里报告的相同问题时。
CSV文件包含正确的版本号。异常报告是
Exception: version conflict for 38dbd4db-240e-4c9b-a927-271fee5db750 expected=1490271991641407488 actual=-1
org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException: version conflict for 38dbd4db-240e-4c9b-a927-271fee5db750 expected=1490271991641407488 actual=-1
temp / temp.2012.0.csv中的第一条记录开始
38dbd4db-240e-4c9b-a927-271fee5db750,1490271991641407488, ...