Обновить конкретное поле в индексе SOLR

Я хочу использовать solr для поиска по статьям

У меня 3 стола:

  1. Группа (идентификатор, название группы)
  2. ArticleBase (id, groupId, какое-то другое поле)
  3. Статья (идентификатор, articleBaseId, заголовок, дата, ...)

в файле solr schema.xml я просто определяю все поля статьи, которые смешиваются с таблицей ArticleBase (для использования одного индекса в solr) следующим образом: (id, articleBaseId, groupId, ...)

проблема: администратор хочет изменить группу (ArticleBase), поэтому я должен обновить (или заменить) все проиндексированные статьи в solr. правильно ?
могу ли я обновить groupId только в индексе solr?

есть какое-нибудь решение?

Примечание: таблица статей содержит более 200 миллионов статей, и я использую solr только для индекса (не храню никаких данных полей, кроме идентификатора статьи)


person Hamid    schedule 09.01.2010    source источник


Ответы (6)


Solr пока не поддерживает обновление отдельных полей, но есть проблема JIRA по этому поводу (на момент написания этой статьи почти 3 года).

Пока это не будет реализовано, вы должны обновить весь документ.

ОБНОВЛЕНИЕ: начиная с Solr 4+ это реализовано, здесь документацию.

person Mauricio Scheffer    schedule 09.01.2010
comment
Позвольте мне просто прокомментировать, что Маурисио имеет в виду только один документ, который необходимо обновить, а не всю вашу таблицу из 200 миллионов статей. - person Eric Pugh; 11.01.2010

Пожалуйста, обратитесь к этому документу об «частичном обновлении документов». "Функция в Solr 4.0

Solr 4.0 теперь финальная и готовая к производству.

Эта функция позволяет обновлять поля и даже добавлять значения в многозначные поля.

Маурисио был прав в своем ответе еще в 2010 году, но так обстоят дела сегодня.

person Stefan    schedule 17.08.2012

SolrPHP не предоставляет никаких методов для обновления определенного поля в Solr.

Однако вы можете вызвать Curl в PHP для обновления определенного поля:

<?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.

person Guillaume Renoult    schedule 10.09.2014
comment
Я неделями искал решение этой проблемы. Большое спасибо за Ваш пост! Наконец-то это работает. - person Brian Powell; 13.07.2016

Мое решение было примерно таким:

$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();
}
person Waqleh    schedule 14.12.2015

Вы можете обратиться к документации для частичного Обновления. Вы можете сделать обновление, заменив его или добавив дополнительные значения в это конкретное поле, хотя (как список) это не требуется в вашем случае.

person user2430771    schedule 28.02.2019

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();  
person Abhijit Bashetti    schedule 19.07.2019