Issue with JsonPath while extracting field from a json string in Scala - scala

I have a json string and I want to extract a parameter from this json using JsonPath in scala. Given Json:
{
"message_version":"2.0",
"message":"1.0",
"message_metadata":{
\"event_type\":\"MerchantRegistrationFraudEvaluation\",
\"event_date\":\"1513665186657\"
}
}
When I tried the below code to extract "event_type" from this json string and it throws an exception:
val eventType = JsonPath.read[String](jsonString, "$.message_metadata.event_type")
Exception:
com.jayway.jsonpath.PathNotFoundException: Expected to find an object with property ['event_type'] in path $['message_metadata'] but found 'java.lang.String'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'
But if I use two separate statements, one to extract message_metadata first then other one to extract event_type as below it works fine:
val eventMetaData = JsonPath.read[String](message, "$.message_metadata") val eventType = JsonPath.read[String](eventMetaData, "$.event_type") eventType // MerchantRegistrationFraudEvaluation.
Can someone help here to get the event_type in a single line?

Related

How to return null if regex fails to match?

I am using spark 2.4 with Scala. I am using regexp_extract() to extract relevant fields from the data:
eg:
I have a sample data:
foo/e/b24449378.277938302;dc_trk_aid=472300787;
I use the following regex to extract the field:
dc_trk_aid=([^\/\?\;\&]+)
It would extract 472300787 based on the regex:
regexp_extract("foo/e/b24449378.277938302;dc_trk_aid=472300787", "dc_trk_aid=([^\/\?\;\&]+)")
However in the case where it does not match eg:
foo/e/b24449378.277938302;dc_trk_cid=472300787;
it returns an empty string. Is there way I can make it to return null besides creating any custom udf to do this operation or replacing empty strings with null on the dataframe.
You can use when...otherwise (basically what the comment above suggests if I'm not mistaken)
val df = Seq("foo/e/b24449378.277938302;dc_trk_aid=472300787", "foo/e/b24449378.277938302;dc_trk_cid=472300787;").toDF()
df.select(regexp_extract($"value", raw"dc_trk_aid=([^\/\?\;\&]+)", 1).as("extract"))
.select(when($"extract" === "", null).otherwise($"extract").as("withNulls")).show()

Parse PGobject in Groovy

I'm trying to parse selected result from PostgreeSQL in Groovy, but something goes wrong, when I'm trying to parse it.
I used a lot of things, but I haven't reached the goal.
I've tried so:
I have three columns in postgre. One of the columns (document) is jsonb type and I want to parse it.
//instance of connection string to postrgre
PgAdmin pg = new
List<GroovyRowResult> result = pg.getSelectResult(Here goes select script)
for(Map oneRow in result) {
def document = oneRow.get("document")
println documnet //Well from here it works good, it prints jsonb data stored in document column.
def customerName = document.get("CustomerName") // it failes and goes on error, where CustomerName is inside jsonB.
}
I've also tried to use JsonSlurper, but it also fails.

how to convert map<anydata> to json

In my CRUD Rest Service I do an insert into a DB and want to respond to the caller with the created new record. I am looking for a nice way to convert the map to json.
I am running on ballerina 0.991.0 and using a postgreSQL.
The return of the Update ("INSERT ...") is a map.
I tried with convert and stamp but i did not work for me.
import ballerinax/jdbc;
...
jdbc:Client certificateDB = new({
url: "jdbc:postgresql://localhost:5432/certificatedb",
username: "USER",
password: "PASS",
poolOptions: { maximumPoolSize: 5 },
dbOptions: { useSSL: false }
}); ...
var ret = certificateDB->update("INSERT INTO certificates(certificate, typ, scope_) VALUES (?, ?, ?)", certificate, typ, scope_);
// here is the data, it is map<anydata>
ret.generatedKeys
map should know which data type it is, right?
then it should be easy to convert it to json like this:
{"certificate":"{certificate:
"-----BEGIN
CERTIFICATE-----\nMIIFJjCCA...tox36A7HFmlYDQ1ozh+tLI=\n-----END
CERTIFICATE-----", typ: "mqttCertificate", scope_: "QARC", id_:
223}"}
Right now i do a foreach an build the json manually. Quite ugly. Maybe somebody has some tips to do this in a nice way.
It cannot be excluded that it is due to my lack of programming skills :-)
The return value of JDBC update remote function is sql:UpdateResult|error.
The sql:UpdateResult is a record with two fields. (Refer https://ballerina.io/learn/api-docs/ballerina/sql.html#UpdateResult)
UpdatedRowCount of type int- The number of rows which got affected/updated due to the given statement execution
generatedKeys of type map - This contains a map of auto generated column values due to the update operation (only if the corresponding table has auto generated columns). The data is given as key value pairs of column name and column value. So this map contains only the auto generated column values.
But your requirement is to get the entire row which is inserted by the given update function. It can’t be returned with the update operation if self. To get that you have to execute the jdbc select operation with the matching criteria. The select operation will return a table or an error. That table can be converted to a json easily using convert() function.
For example: Lets say the certificates table has a auto generated primary key column name ‘cert_id’. Then you can retrieve that id value using below code.
int generatedID = <int>updateRet.generatedKeys.CERT_ID;
Then use that generated id to query the data.
var ret = certificateDB->select(“SELECT certificate, typ, scope_ FROM certificates where id = ?”, (), generatedID);
json convertedJson = {};
if (ret is table<record {}>) {
var jsonConversionResult = json.convert(ret);
if (jsonConversionResult is json) {
convertedJson = jsonConversionResult;
}
}
Refer the example https://ballerina.io/learn/by-example/jdbc-client-crud-operations.html for more details.?

grails-mongodb: findAllBy*InList not returning results in order

I'm using grails2.4.4 with mongodb plugin version 3.0.3. I'm facing issue while getting results of my domain object. I'm using below code:
My domain:
Employee{
ObjectId id
String name
}
I have list of ids , using below code to fetch employees: (Please note that below data is just for representing my problem. In realtime, my ids are random and so i can't use sorting, but i just want the result in the order of input.)
def idsList=[new ObjectId("2001"), new ObjectId("2002"), new ObjectId("2003")]
def results=Employee.findAllByIdInList(idsList)
Expected result:
[Employee#2001,Employee#2002,Employee#2003]
Actual result (not in order):
[Employee#2002, Employee#2003 , Employee#2001] or sometimes
[Employee#2003, Employee#2001 , Employee#2002]
For now i'm doing like this to get the output in desired order:
def results=[]
for(id in idsList){
def emp=Employee.findById(id)
results<<emp
}
But i want to do this with single call(findAllBy*InList) without iterating over objects. Can anyone advise how can i get the results in the order of input ids?
Have you tried
Employee.findAllByIdInList(idsList, [sort: 'id', order:'asc'])
? It should work as expected
If it doesn't, instead of for loop you can use
def result = idList.collect { id -> Employee.findById(id) }

Conversion of a object into a particular datetime format

I want to convert a query string object into a datetime in this format:- "YYYY-mm-dd HH:mm:ss.xxx" in C#.net. But when i am using Convert.ToDateTime(object) for getting the datetime value then an exception is being fired.
Could anyone can provide me the iFormatProvider for the same.?
Thanks
Varun Sareen
Have a look at DateTime.TryParseExact Method
I think your problem is trying to convert the QueryString object, instead of getting a value from the query string and then converting the value.
A QueryString object is a keyed collection of the values specified in a URL from an HTTP request. So if you have a URL like: http://example.com?a=1&b=2&c=3, the request QueryString object will contain three values: 1, 2, and 3. To access the values you would use the keys:
var aValue = Request.QueryString["a"];
And the variable aValue would then contain the string value "1" (without the quotes).
After getting the value from the query string, you can use the TryParseExact method suggested by #astander.