jackson annotation to hide json type - java

I am using spring boot and I use a composite key. I want to hide the type of the JSON object.I tried with the annotations like #jsonIgnore, #jsonIgnoreType and nothing works. I have this:
[ {
"consumoId" : {
"inc_acc_id" : "1069931929",
"inc_clu_cellular_number" : "2954316800",
"inc_description" : "Minutes"
},
"inc_frt_id" : null,
"inc_unit" : "Min.",
"inc_amount" : 0.0,
"inc_quantity" : 22.68
}]
and I expect this:
[ {"inc_acc_id" : "1069931929",
"inc_clu_cellular_number" : "2954316800",
"inc_description" : "Minutes" ,
"inc_frt_id" : null,
"inc_unit" : "Min.",
"inc_amount" : 0.0,
"inc_quantity" : 22.68
}]

It looks like you want to inline the properties under the consumoId parent?
#JsonIgnore would skip it altogether, but #JsonUnwrapped will unwrap (omit) the containing object.

Related

Spring MongoTemplate: Possible to Get and Count all distinct values from Key value Object in each document

I have a large-ish dataset (+100,000) documents. In each document, there is a key value object called ProjectCategories for which I would like to be able to get distinct count on each of the values across the entire collection.
For example my document looks like this:
"_id" : ObjectId("60e5ae42fcc92f14c3a41208"),
"userId" : "xxxx",
"projectCreator" : {
"userId" : "xxx|xxxx"
},
"hashTags" : [
"Spring",
"Java"
],
"projectCategories" : {
"60d76ef0597444095b8ab4b2" : "Backend",
"60d76ef0597444095b8ab232" : "Infrastructure"
},
"createdDate" : ISODate("2021-07-07T13:38:10.655Z"),
"updatedAt" : ISODate("2021-07-08T11:48:36.200Z"),
"_class" : "xxxx.model.project.Project"
}
I would like to get back all the unique values and their counts. Something like this:
Backend : 1002
FrontEnd : 1232
Infrastructure: 902
Is this possible to do using Java and mongoTemplate
Thanks for reading

ObjectMapper for multiple naming strategies

I am dealing with a dataset where both underscores and hyphens are being used between tokens in property names:
{
"id" : "116",
"priority" : 3,
"table_id" : 0,
"hard-timeout" : 0,
"match" : {
"ethernet-match" : {
"ethernet-type" : {
"type" : 2048
}
},
"ipv4-destination" : "10.0.0.25/32"
},
"strict" : false,
"flow-name" : "port_X_to_8_ip",
"instructions" : {
"instruction" : [ {
"order" : 0,
"apply-actions" : {
"action" : [ {
"order" : 1,
"output-action" : {
"max-length" : 60,
"output-node-connector" : "8"
}
} ]
}
} ]
},
Notice most elements have hyphens, but a few use underscores, such as table_id.
On the Java side, I am using this code to create my mapper:
import com.fasterxml.jackson.databind.json.JsonMapper;
...
JsonMapper jsonMapper = JsonMapper.builder().configure(SerializationFeature.INDENT_OUTPUT, true).build();
jsonMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); // <-- combine this
jsonMapper.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); // <-- with this?
The last two lines are my current crux. I want the naming strategy to work for either SNAKE_CASE or KEBAB_CASE however I don't see a way to or the properties and can't find much on google.
You pick the naming strategy that fits for most properties, then use the #JsonProperty() annotation to name the ones that don't follow the standard.
In your case, that would be PropertyNamingStrategy.KEBAB_CASE and #JsonProperty("table_id").

I need to retrieve MongoDB's object just with filtered's array item

I'm needing to retrieve just with two dates, all the documents from my MongoDB's collection, with the filtered items from the array.
This is an example of 2 of my documents;
{
"_id" : ObjectId("5f18fa823406b7000132d097"),
"last_date" : "22/07/2020 23:48:32",
"history_dates" : [
"22/07/2020 23:48:32",
"22/07/2020 00:18:53",
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname" : "MyHostname1",
"ip" : "142.0.111.79",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "LogonUI.exe",
"date" : "23/07/2020 10:26:04",
}
{
"_id" : ObjectId("5f18fa823406b7000132d098"),
"last_date" : "22/07/2020 23:48:33",
"history_dates" : [
"22/07/2020 23:48:33",
"23/07/2020 00:18:53",
],
"hostname" : "MyHostName2",
"ip" : "142.0.111.54",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "svchost.exe",
"date" : "23/07/2020 10:26:04",
}
I'm needing to make a find to my database (Using Spring Data), to retrieve the same objects, but with the "history_dates"'s array filtered between the 2 dates recieved.
For example, if my 2 recieved dates are: "23/07/2020" and "24/07/2020", I want MongoDB to return the next objects;
{
"_id" : ObjectId("5f18fa823406b7000132d097"),
"last_date" : "22/07/2020 23:48:32",
"history_dates" : [
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname" : "MyHostname1",
"ip" : "142.0.111.79",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "LogonUI.exe",
"date" : "23/07/2020 10:26:04",
}
{
"_id" : ObjectId("5f18fa823406b7000132d098"),
"last_date" : "22/07/2020 23:48:33",
"history_dates" : [
"23/07/2020 00:18:53"
],
"hostname" : "MyHostName2",
"ip" : "142.0.111.54",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "svchost.exe",
"date" : "23/07/2020 10:26:04",
}
I'm really ignorant about MongoDB's queries, and I have been trying to make this with Spring Data all the week.
UPDATE 1.
Thanks varman, and do you know how can i just retrieve the documents with filtered arrays not empty?
So basically you need to do filter. MongoTemplate offers a lot of operation for mongodb, if some methods don't exist in MongoTemplate, we can go with Bson Document pattern. In that case, try this article: Trick to covert mongo shell query.
Actually you need a Mongo query something like following. Using $addFields one of the methods shown below. But you can use $project, $set etc. Here $addFields overwrites your history_dates. (It uses to add new fields to document too).
{
$addFields: {
history_dates: {
$filter: {
input: "$history_dates",
cond: {
$and: [{
$gt: ["$$this", "23/07/2020"]
},
{
$lt: ["$$this", "24/07/2020"]
}
]
}
}
}
}
}
Working Mongo playground.
You need to convert this into spring data. So #Autowired the MongoTemplate in you class.
#Autowired
MongoTemplate mongoTemplate;
The method is,
public List<Object> filterDates(){
Aggregation aggregation = Aggregation.newAggregation(
a->new Document("$addFields",
new Document("history_dates",
new Document("$filter",
new Document("input","$history_dates")
.append("cond",
new Document("$and",
Arrays.asList(
new Document("$gt",Arrays.asList("$$this","23/07/2020")),
new Document("$lt",Arrays.asList("$$this","24/07/2020"))
)
)
)
)
)
)
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_CLASS.class), Object.class).getMappedResults();
}
Mongo template doesn't provide add methods for $addFields and $filter. So we just go with bson document pattern. I haven't tested this in Spring.

Spring boot actuator healthcheck (AbstractHealthIndicator) response with indented JSON

I am Spring Boot Actuator /health endpoints to monitor an application but the results is always like that:
"{ "summary" : { "results" : [ ], "duration" : 0, "executionSummaryText" : "Up and running", "failResults" : [ ] }, "applicationID" : "858", "subApplicationID" : "85822", "applicationName" : "app", "subApplicationName" : "app_reg", "applicationVersion" : null, "applicationBuildDate" : "2019-02-28 16:14:09", "applicationBuildLevel" : "5.2.0-SNAPSHOT", "timestamp" : "2019-02-28 17:16:15", "Host" : "host", "workloadStatus" : "Up and running", "detectionTime" : 3, "isaliveStatus" : "ENABLED" }"
but I want it to look like that:
"{
"summary":
{
"results":[],
"duration":0,
"executionSummaryText":"Up and running",
"failResults":[]
},
"applicationID":"858",
"subApplicationID":"85822",
"applicationName":"app",
"subApplicationName":"app_reg",
"applicationVersion":null,
"applicationBuildDate":"2019-02-28 13:19:35",
"applicationBuildLevel":"5.2.0-SNAPSHOT",
"timestamp":"2019-02-28 14:21:33",
"Host":"host",
"workloadStatus":"Up and running",
"detectionTime":4,
"isaliveStatus":"ENABLED"
}"
I tried all of the following but it did not work:
http.mappers.jsonPrettyPrint=true
spring.jackson.serialization.indent_output=true
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
but none of them worked. Is there a configuration to make it work for JSON output?
You need to enable INDENT_OUTPUT serialization feature using properties available in the Appendix A. Assuming you have not created the ObjectMapper bean yourself as per this guide the Spring Boot property is:
spring.jackson.serialization.indent_output=true
Do note this is a global change affect all endpoints which are returning JSON by serializing objects with Jackson.

MongoDB JSON array within JSON object field removal

I have a json object as following:
{ "_id" : ObjectId("508806803bb97dc546e6f307"), "user_name" : "user1", "user_id" : 45645645, "likes" : [ { "event_id" : NumberLong("4578541212") },{ "event_id" : NumberLong("4578541213") } ], "dislikes" : [ ] }
I'm trying to delete specific event within likes array via java drivers
tried doing this first in shell:
> db.users.update( {'likes.event_id' : 4578541212}, { '$unset':{'likes.event_id'
:1}})
with no luck...how can I manage doing that?
If you want to just remove the event_id field from the array element:
db.users.update( {'likes.event_id' : 4578541212}, {'$unset':{'likes.$.event_id' :1}})
Use the $pull operator to delete the element:
db.users.update({'likes.event_id': 4578541212}, {'$pull':{likes: {event_id: 4578541212}}})

Categories