5

作为我的 DSpace 实例的一部分,我有一个 SOLR 存储库,其中包含 1200 万条使用统计记录。一些记录已通过多次 SOLR 升级迁移,不符合当前架构。其中 500 万条记录缺少我的架构中指定的唯一 id 字段。

DSpace 系统提供了一种机制,可以使用以下代码将旧的使用统计记录分片到单独的 solr 分片中。

空间分片逻辑:

        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 提供的分片进程。您能否推荐我应该采取的任何其他措施来修复这些记录?

4

3 回答 3

1

修改生成的 csv 应该更容易。

尝试将 id 添加到 csv 中,直接在第一个方法之前添加一个方法来执行此操作。

FileUtils.copyInputStreamToFile(csvInputstream, csvFile);

//<- 对重新打开 csv 文件并将强制 id 添加到每一行的函数的方法调用

filesToUpload.add(csvFile); //加 10000 & 重新开始 yearQueryParams.put(CommonParams.START, String.valueOf((i + 10000))); }

对于(文件 tempCsv:filesToUpload){

(...)

于 2014-11-18T11:55:00.703 回答
1

SolrLogger 中的分片代码将记录复制到一个新的空核心中。问题是从大约 DSpace 3 开始的 DSpace 使用统计文档包含一个_version_字段,并且该字段在分片时包含在副本中。

当包含_version_字段的文档添加到 Solr 索引时,这会触发 Solr 的乐观并发功能,该功能检查索引中具有相同唯一 ID 的现有文档。逻辑大致是这样的(参见http://yonik.com/solr/optimistic-concurrency/):

  • _version_> 1:文档版本必须完全匹配
  • _version_= 1:文档必须存在
  • _version_< 0:文档不能存在
  • _version_= 0:不关心(如果存在则正常覆盖)

包含_version_值 > 1 的使用统计文档因此使 Solr 在新创建的年份分片中查找具有相同唯一 ID 的现有文档;但是,显然当时没有这样的文件,因此版本冲突。

分片期间的复制过程会创建临时 CSV 文件,然后将其导入新核心。幸运的是,可以告诉 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 中。

于 2015-04-01T22:05:05.777 回答
0

我试图用 400 万条记录将 1.8.3 升级到 4.2,所有记录都缺少 uid 和version。我写了一个从 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, ...

于 2015-01-15T08:45:32.980 回答