Partial document update in SOLR 6.5.1 - solr

I have ID(unique key) and URL fields in my indexed document. They have same values. And I am able to update the URL field(changing the DNS) as following:
{"id":"ABC.com/content/dam/images/infographics/Infographic_Final.pdf","url":{"set":"XYZ.com/content/dam/images/infographics/Infographic_Final.pdf"}}
what i am trying to achieve is i have 1000 documents having field ID starting with ABC.com. It should update URL field with XYZ.com and the rest of the URL-path must remain the same. can i achieve this? i dont want to update URL repeatedly for 1000 times.
Thanks in advance.

if you are asking for a 'bulk update' like SQL's 'UPDATE table WHERE...' that is not possible in Solr. You have to submit each doc (mind you, you can submit many docs in one request, but all doc's info must be in there).

I was able to achieve it using Java program. I used Solr-query to find all ID starting with ABC.com. I got URL corresponding to that ID and replaced ABC.com with XYZ.com and kept the rest of the path same. Used set command and updated all the URLs(only URL field) using while loop.
String urlString = "http://localhost:8090/solr/collectionName";
SolrClient solrClient = new HttpSolrClient.Builder(urlString).build();
SolrQuery query=new SolrQuery();
query.setQuery("id:*ABC*");
query.setRows(2147483647);
QueryRequest req = new QueryRequest(query);
QueryResponse response = req.process(solrClient);
SolrDocumentList docList=response.getResults();
Iterator <SolrDocument> itr=docList.iterator();
String IdValue="";
Map<String, String> cmd1;
Map<String, String> cmd2;
UpdateRequest ureq=new UpdateRequest();
while(itr.hasNext()){
JSONObject resultItems = new JSONObject();
SolrDocument doc= itr.next();
IdValue=(String)doc.getFieldValue("id");
SolrInputDocument newdoc = new SolrInputDocument();
cmd1 = new HashMap<String, String>();
String URL=IdValue.replace("www.ABC.com", "www.XYZ.com");
cmd1.put("set", URL);
newdoc.addField("id", IdValue);
newdoc.addField("url", cmd1);
ureq.add(newdoc);
cmd1=null;
cmd2=null;
}
NamedList res = solrClient.request(ureq);
System.out.println(" response "+res);
solrClient.commit();
solrClient.close();

Related

Finding the ID of a Salesforce Global Value Set

I'm attempting to write an APEX class that will add items to a global valueset, but in order to do so I need to know the ID of the global value set. Is there a way to find the ID of the global valueset (through APEX, not by looking at the URL) that a picklist field is using? Ideally I'd be able to do something similar to:
Case.picklistField__c.getdescribe();
and get a response that includes the ID of the global value set that it uses - that way I can then use my the metadataAPI to update the values.
Alternatively if I could find the global valueset by name I could use that with the metadata api as a work around.
UPDATE: Was able to get this to work using Eyescreams suggestion with the tooling API - full implementation:
String gvsName = 'TestValueSet'; //name of the global valueset you want the Id for goes here
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v41.0/tooling/query/?q=select+id+from+globalvalueset+Where+developername='+gvsName);
req.setMethod('GET');
Http httpreq = new Http();
HttpResponse res = httpreq.send(req);
system.debug(res.getBody());
SELECT Id, FullName, Description
FROM GlobalValueSet
But it's not available in straight Apex queries, you'd need Tooling API (meaning a REST callout). You can play with it in Developer Console -> Query Editor, just check the tooling api checkbox on bottom
These days you need to escape the variable like this:
String gvsName = 'TestValueSet'; //name of the global valueset you want the Id for goes here
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v48.0/tooling/query/?q=select+id+from+globalvalueset+Where+developername=\''+gvsName+'\'');
req.setMethod('GET');
Http httpreq = new Http();
HttpResponse res = httpreq.send(req);
system.debug(res.getBody());

Named Credential

I want to access the URL of the named credential and want to dynamically add some query parameters to it. Is it possible? Like in case of custom settings I access the value by get values directly. Does the named credential global variable credential provides me any such opportunity?
Refer to the documentation here:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm
This example is used:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:***My_Named_Credential***/some_path');
As long as your named credential URL contains the protocol, subdomain (if required), hostname and port (id required) then you can append the path, parameters or fragments.
For example:
Map<String, String> urlParameters = new Map<String, String>{'client_id','12345'};
String urlParameterString = '';
for (String param : urlParameters.keySet()) {
urlParameterString += param+'='+urlParameters.get(param);
}
HttpRequest req = new HttpRequest();
req.setEndpoint(
String.format(
'callout:GoogleAPI/{0}?{1}#{2}',
new String[]{'oauth2', urlParameterString, 'anchorId'}
)
);
If the named credential URL was:
https://api.google.com
That endpoint should then be something like this:
https://api.google.com/oauth2?client_id=12345#anchorId

new field not showing up in Solr

our Solr schema is open so we dont need to define a new particular field.
when I send a Json request to sava a new document to Solr, I added a new field lang_sx and I do :
UpdateResponse response = server.addBeans(list);
System.out.println(response.getStatus());
server.commit();
response.getStatus() shows me that the request was successful but I don't see this new field in Solr.

quoted format json from Solrj

It looks like the QueryResponse from Solrj has no mean to give you a quoted Json string with wt=on or not. All I received is something like this
{responseHeader={status=0,QTime=2,params= {fl=id,productName,imageFront,priceEng,priceEngExp...
Question:
1) Am I missing something here ? Or there is no way to get the json response properly from the Solr server by Solrj.
2) Now on my client, if I convert the non-quoted json string from Solrj, does it mean it was done two times, once in server time and one in the Solrj client time ?
You can get JSON response by setting wt=json to the Solr query. Example URL is shown below :
localhost:8983/solr/select/?q=:&rows=10&indent=on&wt=json
You can't get JSON response using Solrj. You don't need to use Solrj for this purpose.By sending HTTP requests to the URL above, you can get json response.
With newer versions of Solr (starting with 4.7.0) it is possible to return the query response directly in json-format. This can be done with the NoOpResponseParser.
SolrQuery query = new SolrQuery();
QueryRequest req = new QueryRequest(query);
NoOpResponseParser rawJsonResponseParser = new NoOpResponseParser();
rawJsonResponseParser.setWriterType("json");
req.setResponseParser(rawJsonResponseParser);
NamedList<Object> resp = mySolrClient.request(req);
String jsonResponse = (String) resp.get("response");
System.out.println(jsonResponse );

Update existing SalesForce lead field with httpWebRequest

I have looked everywhere, but have not found a solution for this issue. I am trying to update a field in SalesForce for a lead. The way I have it sending right now is:
string postData = string.Format("Data I am Sending");
//send data
var data = Encoding.UTF8.GetBytes(postData);
try {
WebRequest request = WebRequest.Create("https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
}
catch { }
instead of it creating a new entry, I want it to update the other fields of the lead where the email address matches the data I send it. So something like:
postData = "oid=myOid&email=" + emailIWantToMatch.Text + "...";
Is this possible or will I have to use the apex api?
The Web2Lead feature can only create new leads, not update existing ones. To do updates you'll need to use either the soap or rest API
Or you can create a Force.com Site Web2Lead page (Creating a Web-to-Lead Form for Your Force.com Site) and have your controller the logic to insert/update based on email-id.

Resources