I have a Solr index in a core having 3000 documents.
I want to modify the value of a single field in the entire core based on unique key PaperID.
I'm using the following java code but instead of updating the existing value it adds new documents.
if (solrDocument.get("PaperID").equals(solrDocument2.get("PaperID"))) {
String Mscore = (String) solrDocument.get("ID");
String ModifyScore = (String) solrDocument.get("Author");
//solrDocument.setField("ID", ModifyScore);
//update the field
System.out.println(Mscore);
System.out.println(ModifyScore);
System.out.println(solrDocument2.get("Mscore") + "\n");
SolrInputDocument sid = new SolrInputDocument();
Map<String, Object> fieldModifier = new HashMap<String, Object>(1);
fieldModifier.put("set", ModifyScore);
sid.setField("ID", fieldModifier);
//solr.add(sid);
solr.commit();
}
can anyone guide me accordingly...Best Regards
Your code isn't changing anything, since you've commented out the .add command. And you have to use the actual ID in the ID field, since Solr won't know what document to update otherwise. The field you're changing should have the fieldModifier attached:
SolrInputDocument doc = new SolrInputDocument();
Map<String, String> fieldModifier = new HashMap<String, String>();
// Change ModifyScore to the new value, since you're just using the current value now..
fieldModifier.put("set", ModifyScore);
doc.addField("ID", Mscore);
doc.addField("Author", fieldModifier);
solr.add(doc);
solr.commit();
Related
I'm trying to use sObject to dynamically change Name field objects across while organization.
I've tried using SomeId.getSObjectType().newSObject(SomeId) to create the sObject, but when I try to change the Name field I have error
Variable does not exist: Name
Map<Id, string> idsToUpdate = new Map<Id, string>();
// Put the Id's and associated name values in the map
List<SObject> sObjectsToUpdate = new List<SObject>();
foreach(Id idToUpdate : idsToUpdate.keySet) {
SObject o1 = idToUpdate.getSObjectType().newSObject(idToUpdate);
o1.Name = idsToUpdate.get(idToUpdate);
sObjectsToUpdate.add(o1);
}
update sObjectsToUpdate;
As I can see other posts, this is the way of creation dynamic update of objects.
Any idea why this happens?
Not all objects have a name field, you should check for the existence of the name field before trying to set the field also you must use the put method
Map <String, Schema.SObjectField> fieldMap = o1.getSobjectType().getDescribe().fields.getMap();
if(fieldMap.containsKey('Name')){
o1.put('Name', 'Test');
}
My app receives JSON responses from an API. When it arrives, the app uses the JSONParser class to get a result as a Map:
JSONParser jp = new JSONParser();
Map <String, Object> result = jp.parseJSON(new InputStreamReader(input, "UTF-8"));
The "result" contains 2 values. First a URL that I can get using the key "url":
String url = result.get("url");
And second, another set of data which is in JSON format and I get using the key "eager". I tried to extract it to a Map:
java.util.List<Map<String, Object>> eager = (java.util.List<Map<String, Object>>) result.get("eager");
The resulting Map does not behave like a Map, so I passed the whole eager Map to a String, just to check the content and I noticed that the data is inside brackets, like this:
[{item1=x, item2=x,.....itemN=x}]
Question:
How can I get the data as a JSON object?
You parse your result String as a List. What happend if you try to get "data" like this ?
java.util.List<Map<String, Object>> newResult = (java.util.List<Map<String, Object>>) result.get(0);
You need to use the key "root" not "data" to get your list.
"result" is a Map.
"eager" is a List of Maps.
You need to get the first position of the eager Map in order to get the Map with the data:
Map <String, Object> result = jp.parseJSON(new InputStreamReader(input, "UTF-8"));
java.util.List<Map<String, Object>> eager = (java.util.List<Map<String, Object>>) result.get("eager");
Map<String, Object> eagerMap = (Map<String, Object>) eager.get(0);
I want to update a particular field of a document in solr. However while trying to do so other
fields of the document are becoming null.
CommonsHttpSolrServer server = new CommonsHttpSolrServer("http://mydomain:8983/solr/index_socialmedia/");
List<SolrInputDocument> solrInputDocsList = new ArrayList<SolrInputDocument>();
SolrInputDocument solrInputDoc = new SolrInputDocument();
solrInputDoc.addField("id","427832898745234516478592");
solrInputDoc.addField("city","Kolkata");
solrInputDocsList.add(solrInputDoc);
server.add(solrInputDocsList);
server.commit();
In the above code the "id" field is the unique field.
How can I fix this problem.
I tried with the following code snippet. It's able to do partial update. Try this.
SolrServer server = new HttpSolrServer("http://mydomain:8983/solr/index_socialmedia/");
SolrInputDocument solrInputDoc = new SolrInputDocument();
Map<String, String> update = new HashMap<String, String>();
update.put("set", "Kolkata");
solrInputDoc.addField("id","427832898745234516478592");
solrInputDoc.addField("city", update);
server.commit();
Set <uniqueKey>id</uniqueKey> in your solr schema.xml
Which solr version are you using ?
if it is bellow 4.0 ,solr does not support single field update (partial update)
so in your case existing old document is deleted and new document is inserted with same id
(Reason Solr does not support single field or partial update is lucene does not support partial update )
If you using Solr 4.0 you can refer this solrj api for partial document update
Solr 4.x has this nice new feature that lets you specify how, when doing an update on an existing document, the multiValued fields will be updated. Specifically, you can say if the update document will replace the old values of a multivalued field with the new ones, or if it should append the new values to the existing ones.
I've tried this using the request handler, as described here:
http://wiki.apache.org/solr/UpdateXmlMessages#Optional_attributes_for_.22field.22
I've used curl to send xml where some fields used the update=add option:
<field name="skills" update="add">Python</field>
This works as expected.
However I can't get how to do this the Java API (SolrJ).
If I do something like this:
SolrInputDocument doc1 = new SolrInputDocument();
doc1.setField("ID_VENTE", "idv1");
doc1.setField("FACTURES_PRODUIT", "fp_initial");
solrServer.add(doc1);
solrServer.commit();
SolrInputDocument doc2 = new SolrInputDocument();
doc2.setField("ID_VENTE", "idv1");
doc2.setField("FACTURES_PRODUIT", "fp_2");
solrServer.add(doc2);
solrServer.commit();
The value for the field "FACTURES_PRODUIT" becomes "fp_2" (the initial value is lost).
I've also tried:
doc2.addField("FACTURES_PRODUIT", "fp_2");
but the result is the same. I've also looked into the SolrInputField class but haven't found anything similar to this.
So, my question is, how can I use the Solr 4 Java API to updated values into a multiValued field by appening (not replacing) the new values?
Ok, I solved it after debugging a bit the SolrJ code. You have to do this:
SolrInputDocument doc2 = new SolrInputDocument();
Map<String,String> fpValue2 = new HashMap<String, String>();
fpValue2.put("add","fp2");
doc2.setField("FACTURES_PRODUIT", fpValue2);
I have the following query which I took from my URL
public static String query="pen&mq=pen&f=owners%5B%22abc%22%5D&f=application_type%5B%22cde%22%5D";
public static String q="pen";
I parsed my query string and took each facetname and facet value from it and stored in a map
String querydec = URLDecoder.decode(query, "UTF-8");
String[] facetswithval = querydec.split("&f=");
Map<String, String> facetMap = new HashMap<String, String>();
for (int i = 1; i < facetswithval.length; i++) {
String[] fsplit = facetswithval[i].split("\\[\"");
String[] value = fsplit[1].split("\"\\]");
facetMap.put(fsplit[0], value[0]);
}
Then i use the following code to query in solr using solrj
CommonsHttpSolrServer server = new CommonsHttpSolrServer("http://localhost:8983/solr/");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(q);
for (Iterator<String> iter = facetMap.keySet().iterator(); iter.hasNext();){
String key=iter.next();
System.out.println("key="+key+"::value="+facetMap.get(key));
solrQuery.setFilterQueries(key+":"+facetMap.get(key));
}
solrQuery.setRows(MAX_ROW_NUM);
QueryResponse qr = server.query(solrQuery);
SolrDocumentList sdl = qr.getResults();
But after running my code I found out that solrQuery.setFilterQuery method is setting filter for only last set facet. That means if i m running the loop and using this function three times it is taking the last set filter values only.
Can somebody please clarify this and tell me better approach for doing this. Also I am decoding url. So, if my facet contains some special character in the middle then i am not getting any result for that. I tried using it without encoding also but it didnt work. :(
There is also a addFilterQuery method, I would call that since you are setting the filter queries individually in your for loop.
Also, please see this post Filter query with special character using SolrJ client from the Solr Users Mailing List about the need to still escape special characters in queries.