gpt4 book ai didi

solr - 规范化 SOLR 记录以进行分片 : _version_ issues

转载 作者:行者123 更新时间:2023-12-02 03:13:37 25 4
gpt4 key购买 nike

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

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

DSPACE 分片逻辑:

        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_ 字段值相关的错误,并且进程终止。如果我尝试显式设置 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 提供的分片进程。您能否建议我应该采取任何其他措施来修复这些记录?

最佳答案

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

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

  • _version_ > 1: Document version must exactly match
  • _version_ = 1: Document must exist
  • _version_ < 0: Document must not exist
  • _version_ = 0: Don't care (normal overwrite if exists)

包含_version_值> 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 中。

关于solr - 规范化 SOLR 记录以进行分片 : _version_ issues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26941260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com