更新SOLR索引的特定字段

时间:2010-01-09 08:28:22

标签: lucene solr rdbms

我想使用solr搜索文章

我有3张桌子:

  1. 组(ID,组名)
  2. ArticleBase(id,groupId,其他一些字段)
  3. 文章(id,articleBaseId,title,date,...)
  4. 在solr schema.xml文件中的

    我只是定义与ArticleBase表混合的所有文章字段(在solr上使用一个索引),如下所示:(id,articleBaseId,groupId,...)

    问题:管理员想要更改组(ArticleBase),因此我必须更新(或替换)solr中的所有索引文章。对 ?
    我可以只在solr索引中更新groupId吗?

    有任何解决方案吗?

    注意:文章表包含超过2亿篇文章,我只使用solr作为索引(不存储除文章ID之外的任何字段数据)

6 个答案:

答案 0 :(得分:34)

Solr does not support updating individual fields但是有一个JIRA issue about this(截至撰写本文时差不多3岁)。

在实施之前,您必须更新整个文档。

更新:从Solr 4+开始实施,here's the documentation

答案 1 :(得分:15)

有关Solr 4.0中的“部分文档更新”功能,请参阅this document

Solr 4.0现已成为最终版并且已准备就绪。

此功能可以更新字段,甚至可以将值添加到multiValued字段。

毛里西奥在2010年的回答是正确的,但这就是今天的事情。

答案 2 :(得分:4)

SolrPHP不提供更新Solr中特定字段的任何方法。

但是,您可以在PHP中进行Curl调用以更新特定字段:

<?php
// Update array
$update = array(
    'id' => $docId,
    $solrFieldName => array(
        'set' => $solrFieldValue
    )
);
$update = json_encode(array($update));

// Create curl resource and URL
$ch = curl_init('http://'.SOLR_HOSTNAME.':'.SOLR_PORT.'/'.SOLR_COLLECTION.'/update?commit=true');

// Set Login/Password auth (if required)
curl_setopt($ch, CURLOPT_USERPWD, SOLR_LOGIN.':'.SOLR_PASSWORD);

// Set POST fields
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $update);

// Return transfert
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// Set type of data sent
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

// Get response result
$output = json_decode(curl_exec($ch));

// Get response code
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Close Curl resource
curl_close($ch);

if ($responseCode == 200)
{
    echo 'SOLR: Updated successfully field '.$solrFieldName.' for id:'.$docId.' (query time: '.$output->responseHeader->QTime.'ms).';
}
else
{
    echo ('SOLR: Can\'t update field '.$solrFieldName.' for id:'.$docId.', response ('.$responseCode.') is: '.print_r($output,true));
}

我使用此代码在JSON中更新,您也可以使用XML提供数据。

答案 3 :(得分:1)

我的解决方案如下:

$client = new SolrClient($options);
$query = new SolrQuery();
// Find old Document
$query->setQuery('id:5458');
$query->setStart(0);
$query->setRows(1);
$query_response = $client->query($query);
// I had to set the parsemode to PARSE_SOLR_DOC
$query_response->setParseMode(SolrQueryResponse::PARSE_SOLR_DOC);
$response = $query_response->getResponse();
$doc = new SolrInputDocument();
// used the getInputDocument() to get the old document from the query
$doc = $response->response->docs[0]->getInputDocument();
if ($response->response->numFound) {
    $second_doc = new SolrInputDocument();
    $second_doc->addField('cat', "category123");
// Notice I removed the second parameter from the merge()
    $second_doc->merge($doc);
    $updateResponse = $client->addDocument($second_doc);
    $client->commit();
}

答案 4 :(得分:0)

您可以参考此documentation进行部分更新。您可以通过替换或在该特定字段中添加更多值来进行更新,尽管(例如列表)在您的情况下不是必需的

答案 5 :(得分:0)

Solr支持不同类型的更新操作。

Solr支持的一组更新操作。

'add'-向现有Solr文档字段中添加一个或多个新值,或添加一个新字段和一个或多个值。

'set'-更改现有Solr文档字段中的值。

'remove'-从现有Solr文档字段中删除所有出现的值。

这是一个如何通过Solr’s Java客户端SolrJ

进行部分更新的示例。
// create the SolrJ client
HttpSolrClient solrClient = new HttpSolrClient("http://localhost:8983/solr");
// for clould there is CloudSolrClient api

// create the document
SolrInputDocument solrDocument = new SolrInputDocument();
solrDocument.addField("id","12345");
Map<String,Object> solrUpdates = new HashMap<>(1);
solrUpdates.put("address","Pune");
solrDocument.addField("cat", solrUpdates); 

solrClient.add( solrDocument );  
solrClient.close();