Google ADS api - get columns by key (googleAdsRow) - java

I use the google ads API, I get data by query and I want to write the data to a file.
try (GoogleAdsServiceClient googleAdsServiceClient = client.getLatestVersion()
.createGoogleAdsServiceClient()) {
String query = queryData.getQuery();
String customerId = account.toString();
SearchGoogleAdsStreamRequest request = SearchGoogleAdsStreamRequest.newBuilder()
.setCustomerId(customerId)
.setQuery(query)
.build();
for (SearchGoogleAdsStreamResponse searchResponse : stream) {
List<GoogleAdsRow> results = searchResponse.getResultsList();
for (GoogleAdsRow googleAdsRow : results) {
googleAdsRow.getCustomer().getCurrencyCode();
...
I search generic code to go through all the columns and write them and not to go line by line like the following example:
line.append(googleAdsRow.getMetrics().getActiveViewCtr()).append(comma);
line.append(googleAdsRow.getMetrics().getActiveViewImpressions()).append(comma);
line.append(googleAdsRow.getMetrics().getActiveViewMeasurability()).append(comma);
line.append(googleAdsRow.getMetrics().getActiveViewMeasurableCostMicros()).append(comma);
line.append(googleAdsRow.getMetrics().getActiveViewMeasurableImpressions()).append(comma);
line.append(googleAdsRow.getAdGroup().getId()).append(comma);
line.append(googleAdsRow.getAdGroup().getName()).append(comma);
line.append(googleAdsRow.getAdGroup().getStatus()).append(comma);
line.append(googleAdsRow.getSegments().getAdNetworkType()).append(comma);
line.append(googleAdsRow.getMetrics().getAllConversionsFromInteractionsRate()).append(comma);
I thought to convert the googleAdsRow/searchResponse to JSON/map and get column value by key, the key will be the columns name list from YAML (50 columns), but I could not convert the object to JSON.
Example:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.writeValueAsString(googleAdsRow.getMetrics())
Error:
com.fasterxml.jackson.databind.JsonMappingException: Direct
self-reference leading to cycle (through reference chain:
com.google.ads.googleads.v10.common.Metrics["unknownFields"]->com.google.protobuf.UnknownFieldSet["defaultInstanceForType"])
Notes:
The order of the columns that repent is different from the order I requested in the query and I need to list the columns to the file in the order I requested.
Additional columns (which I did not request) are returned in the query, like resourcename, id and I need to filter them.
How to do that in Java? Do you have any ideas for writing a generic code to go through all the columns?

Related

Java Spark: How to get value from a column which is JSON formatted string for entire dataset?

Needs some help here. I am trying to read data from Hive/CSV. There is a column whose type is string and the value is json formatted string. It is something like this:
| Column Name A |
|----------------------------------------------------------|
|"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"|
How can I get the value of key_2 and insert it to a new column?
I tried to create a new function to the get value via Gson
private BigDecimal getValue(final String columnValue){
JsonObject jsonObject = JsonParser.parseString(columnValue).getAsJsonOBject();
return jsonObject.get("key").getAsJsonObject().get("key_1").getAsJsonObject().get("key_2").getAsJsonArray().get(0).getAsBigDecimal();
}
But how i can apply this method to the whole dataset?
I was trying to achieve something like this:
Dataset<Row> ds = souceDataSet.withColumn("New_column", getValue(sourceDataSet.col("Column Name A")));
But it cannot be done as the data types are different...
Could you please give any suggestions?
Thx!
hx!
------------------Update---------------------
As #Mck suggested, I used get_json_object.
As my value contains "
"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"
I used substring to removed " and make the new string like this
{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}
Code for substring
DataSet<Row> dsA = sourceDataSet.withColumn("Column Name A",expr("substring(Column Name A, 2, length(Column Name A))"))
I used dsA.show() and confirmed the dataset looks correct.
Then I used following code try to do it
Dataset<Row> ds = dsA.withColumn("New_column",get_json_object(dsA.col("Column Name A"), "$.key.data.key_2[0]"));
which returns null.
However, if the data is this:
{"key":{"data":{"key_2":[456]}}}
I can get value 456.
Any suggestions why I get null?
Thx for the help!
Use get_json_object:
ds.withColumn(
"New_column",
get_json_object(
col("Column Name A").substr(lit(2), length(col("Column Name A")) - 2),
"$.key.data.key_2[0]")
).show(false)
+----------------------------------------------------------+----------+
|Column Name A |New_column|
+----------------------------------------------------------+----------+
|"{"key":{"data":{"key_1":{"key_A":[123]},"key_2":[456]}}}"|456 |
+----------------------------------------------------------+----------+

How to map Json (from procedure) to Java object

I have the following SP (SQL server) that return a Json output.
BEGIN
SET #jsonOutput = (
SELECT
Program.Name AS ProgramName,
ProgramOwner.FirstName AS OwnerFirstName,
FROM ProgramOwner, Program
WHERE Program.Id = ProgramOwner.ProgramOwner2Program
FOR JSON PATH,WITHOUT_ARRAY_WRAPPER)
I would like to map the return Json output to a List of ProgramDto via modelMapper. Not sure hot to do that since the return values from call.execute is an Object.
Something like this:
SimpleJdbcCall call = new
SimpleJdbcCall(jdbcTemplate).withProcedureName(programProc).declareParameters(
new SqlOutParameter("jsonOutput", Types.VARCHAR));
Map<String,Object>out = call.execute(new MapSqlParameterSource());
if(out.size()>0) {
// Only to show what I am trying to do
Type rootType = new TypeToken<List<ProgramDto>>() {}.getType();
modelMapper.map(out.get("jsonOutput"),rootType );
}
Thank you
As I understood you are trying to get a list of object from
You can use Jackson api
Like this
say for example your json is in variable named jsonData, then you can get the object you need like below.
ObjectMapper mapper = new ObjectMapper();
List<Type> myList = Arrays.asList(mapper.readValue(jsonData, Type[].class));
You can also find more examples here

Trouble with getting strings into JSON

My servlet recieves/loads multiple parameters from/for an article (price, id, count, name).
While they are saved in the session for other purposes I want to display them in a Shopping cart.
So my idea was to get all values into a json like this
{"id":1, "prductName":"article1"}
but my json always ends up empty.
I had two approaches:
String prname = request.getParameter("name");
String anz = String.valueOf(session.getAttribute("Anzahl"));
String prid = request.getParameter("id");
String price = request.getParameter("price");
These are my parameters:
First try:
class ToJson{
String prname1 = String.valueOf(session.getAttribute("prname"));
String anz1 = String.valueOf(session.getAttribute("Anzahl"));
String prid1 = String.valueOf(session.getAttribute("id"));
String price1 = String.valueOf(session.getAttribute("price"));
}
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn1 = jsonb.toJson(obj);
Ends up with: {}
Second try:
ArrayList<String> ar = new ArrayList<String>();
ar.add(prname);
ar.add(price);
ar.add(prid);
ar.add(anz);
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn = jsonb.toJson(ar);
Ends up with: ["P1neu","25","1","145"]
It isn't in a format I wanted and I also don't know how to access the seperate values here, I tried jsn[1] but it didnt work.
Could you help me, please?
To your first question, why JSON object is printing empty:
You are missing getters & setters in the ToJSON class for JSON Builder/Parser to access the properties/fields, and that's why its printing as empty object.
To your second question, how do I access JSON properties:
JSON representation is a natively a string representation, and you can't read part of string as jsn[1].
For reading JSON object properties, you convert it into POJO using available any of preferred open source parser libraries like Jacksons, Gson etc. And then access POJO properties using standard java getter/setters.

retrieve docs from monogdb collection with field condition

I am trying to query a mongodb collection and retrieve certain documents based on a field value but also only retrieve a single field per record. I tried the following but no getting the solution I want:
MongoCollection<Document> collection =
database.getCollection("client_data");
//Document document = collection
// .find(new BasicDBObject("sampleUser", "myDb"))
//.projection(Projections.fields(Projections.include("address"),
//Projections.excludeId())).first();
BasicDBObject aQuery = new BasicDBObject();
aQuery.put("clientId",567);
FindIterable<Document> iterDoc = collection.find(aQuery);
The following retrieves all documents for clientid = 567, but I only want to show the address field.
The commented out code was also what I tried but not sure how to combine that with the query.
EDIT:
I am now able to iterate through all the results but would like to parse each document; I tried parsing the document into my class object but it immediately gives an error:
Unrecognized field "_id" (class
model.Client), not marked as ignorable
But _id is the very first field in the document:
Document{{_id=6216a7f64cedfd00011c35a5,
So I tried something else rather using the first document but then I don't know how to get the next document:
while(cursor.hasNext()) {
// System.out.println(cursor.next().toJson());
Client client = new Client();
try {
JsonParser jsonParser = new JsonFactory().createParser(cursor.next().toJson());
ObjectMapper mapper = new ObjectMapper();
ObjectNode rootNode = mapper.createObjectNode();
String customerInfo = fi.first().toJson();
JsonNode jobj = mapper.readTree(customerInfo);
// this gives the error// client = mapper.readValue(jsonParser,Client.class);
client.setId(jobj.path("_id").path("$oid").asText());
Please advise.
In order to:
retrieves all documents for clientid = 567, but I only want to show the address field
You would execute the following:
collection
.find(Filters.eq("clientId", 567))
.projection(Projections.fields(
Projections.include("address"),
Projections.excludeId())
).first()
Breaking it down:
.find(Filters.eq("clientId", 567)): apply the predicate 'where clientId = 567'
.projection(Projections.fields(Projections.include("address"), Projections.excludeId())): let the response include the address field and exclude the _id field

Google datastore - querying on key values

I have a EntityKind SuggestedInterest.
When I populate that with a key "GrpId" and property "suggestedint".
Now, I need the "suggestedint" value for a requested "GrpId"
So, I write the query as:
String findSuggestedInterest(String grpId)
{
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Filter filter = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY,FilterOperator.EQUAL,grpId);
Query q0 = new Query("SuggestedInterest").setFilter(filter);
PreparedQuery pq0 = datastore.prepare(q0);
Entity result = pq0.asSingleEntity();
return result.getProperty("suggestedint").toString();
}
When I execute this code I get
java.lang.IllegalArgumentException: __key__ filter value must be a Key
The developer docs told to use Entity.KEY_RESERVED_PROPERTY to query on keys, but I guess I misunderstood. What is the correct way to query on key ?
You should pass it a Key instead of String:
Key grpKey = KeyFactory.createKey("SuggestedInterest", grpId)
then use it:
Filter filter =
new FilterPredicate(Entity.KEY_RESERVED_PROPERTY,FilterOperator.EQUAL,grpKey);

Categories