18
votes

I want to using solr for search on articles

I have 3 table:

  1. Group (id , group name)
  2. ArticleBase (id, groupId, some other field)
  3. Article(id, articleBaseId, title, date, ...)

in solr schema.xml file i just define all article field that mixed with ArticleBase table (for use one index on solr) like this: (id, articleBaseId, groupId, ...)

problem: Admin want to change group (ArticleBase), therefore i must update (or replace) all indexed article in solr. right ?
can i update groupId only in solr index ?

have any solution ?

Note:Article table contains more than 200 million article, and i using solr for index only (not store any field data except article id)

6

6 Answers

34
votes

Solr does not support updating individual fields yet, but there is a JIRA issue about this (almost 3 years old as of this writing).

Until this is implemented, you have to update the whole document.

UPDATE: as of Solr 4+ this is implemented, here's the documentation.

15
votes

Please refer to this document about the "Partial Documents Update" Feature in Solr 4.0

Solr 4.0 is now final and production-ready.

This feature makes it possible to update fields and even adding values to multiValued fields.

Mauricio was right with his answer back in 2010, but this is the way things are today.

4
votes

SolrPHP doesn't provide any method to update a specific field in Solr.

However, you can make a Curl call in PHP to update a specific field:

<?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));
}

I use this code to update in JSON, you can also provide data in XML.

1
votes

My Solution was something as below:

$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();
}
0
votes

You can refer to this documentation for Partial Updates. You can make an update either by replacing it or adding more values to that particular field although (like a list), it's not required in your case

0
votes

Solr supports different types of Update Operations.

The set of update operations supported by Solr.

'add' - add a new value or values to an existing Solr document field, or add a new field and value(s).

'set' - change the value or values in an existing Solr document field.

'remove' - remove all occurrences of the value or values from an existing Solr document field.

Here is an example of how to do a partial update via Solr’s Java client, 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();