Java 8 group parent child objects - java

I have a list of java POJO that's coming from a third party mysql stored procedure that includes location information mainly region,city,building and floor and the incident count for each location grouped by floors. I need to aggregate the incident count for each region,city and building as well. I also need to collect the children under each parent in a POJO as a location tree:
how can I do this with java stream api ? Thanks in advance!
input data :
output json :
[{
label : "EMEA",
type : "REGION",
incidentCount : 78,
children : [
{
label : "PAIS",
type : "CITY",
incidentCount : 37,
children : [
{
label: "F1",
TYPE : "FLOOR",
incidentCount: 18
},
{
label: "F2",
TYPE : "FLOOR",
incidentCount: 19
},
...
]
},
...
]
},
...
]

Related

How to get the count of element with non-empty-array-field when group in mongodb aggregate using Spring Data Mongo?

I have the following documents in one collection named as mail_test. Some of them have a tags field which is an array:
/* 1 */
{
"_id" : ObjectId("601a7c3a57c6eb4c1efb84ff"),
"email" : "aaaa#bbb.com",
"content" : "11111"
}
/* 2 */
{
"_id" : ObjectId("601a7c5057c6eb4c1efb8590"),
"email" : "aaaa#bbb.com",
"content" : "22222"
}
/* 3 */
{
"_id" : ObjectId("601a7c6d57c6eb4c1efb8675"),
"email" : "aaaa#bbb.com",
"content" : "33333",
"tags" : [
"x"
]
}
/* 4 */
{
"_id" : ObjectId("601a7c8157c6eb4c1efb86f4"),
"email" : "aaaa#bbb.com",
"content" : "4444",
"tags" : [
"yyy",
"zzz"
]
}
There are two documents with non-empty-tags, so I want the result to be 2.
I use the the following statement to aggregate and get the correct tag_count:
db.getCollection('mail_test').aggregate([{$group:{
"_id":null,
"all_count":{$sum:1},
"tag_count":{"$sum":{$cond: [ { $ne: ["$tags", undefined] }, 1, 0]}}
//if replace `undefined` with `null`, I got the tag_count as 4, that is not what I want
//I also have tried `$exists`, but it cannot be used here.
}}])
and the result is:
{
"_id" : null,
"all_count" : 4.0,
"tag_count" : 2.0
}
and I use spring data mongo in java to do this:
private void test(){
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(new Criteria()),//some condition here
Aggregation.group(Fields.fields()).sum(ConditionalOperators.when(Criteria.where("tags").ne(null)).then(1).otherwise(0)).as("tag_count")
//I need an `undefined` instead of `null`,or is there are any other solution?
);
AggregationResults<MailTestGroupResult> results = mongoTemplate.aggregate(agg, MailTest.class, MailTestGroupResult.class);
List<MailTestGroupResult> mappedResults = results.getMappedResults();
int tag_count = mappedResults.get(0).getTag_count();
System.out.println(tag_count);//get 4,wrong
}
I need an undefined instead of null but I don't know how to do this,or is there are any other solution?
You can use Aggregation operators to check if the field tags exists or not with one of the following constructs in the $group stage of your query (to calculate the tag_count value):
"tag_count":{ "$sum": { $cond: [ { $gt: [ { $size: { $ifNull: ["$tags", [] ] }}, 0 ] }, 1, 0] }}
// - OR -
"tag_count":{ "$sum": { $cond: [ $eq: [ { $type: "$tags" }, "array" ] }, 1, 0] }
Both, return the same result (as you had posted).

Trim the redundant data

I want to delete the data on the date basis(which is present inside the array). This is how my mongo document looks like.
{
"_id" : ObjectId("5d3d94df83f68f8bf751f367"),
"branchName" : "krishYogaCenter",
"Places" : [
"Pune",
"Bangalore",
"Hyderabad",
"Delhi"
],
"rulesForDateRanges" : [
{
"fromDate" : ISODate("2019-01-07T18:30:00.000Z"),
"toDate" : ISODate("2019-03-06T18:30:00.000Z"),
"place" : "Delhi",
"ruleIds" : [
5,
6,
7
]
},
{
"fromDate" : ISODate("2019-03-07T18:30:00.000Z"),
"toDate" : ISODate("2019-05-06T18:30:00.000Z"),
"place" : "Hyderabad",
"ruleIds" : [
1,
2
]
}
],
"updatedAt" : ISODate("2019-07-28T12:31:35.694Z"),
"updatedBy" : "Theia"
}
Here, if "toDate" is less than today I want to delete that object from the array "rulesForDateRanges". Searched on the google but did not get any way to do this in morphia.
If this date was not present internally in the array object then I could have used "delete document where the date is less than today". Here I want to remove that object from the array which is in no longer use, and if the array "rulesForDateRanges" becomes empty in that case only want to delete the whole document.
I am using morphia. Please suggest the way to do this in morphia or the query to do this.
Searched on google got this: We can get the document one by one from the collection using query and do UpdateOperation over that document. But here I have to perform updateOperation for each and every document.

Merge list of duplicate Faceitfields in solr using java

I Have a List of Facet fields added in a loop, these loops add all faceits fetched from solr faceit results, which has duplicate entry in final facieit field 'allFacetFields',
[
movie-1:[
manufaturer(10),
producers(5),
actors(12)
],
movie-2:[
manufaturer(10),
producers(5),
actors(12)
],
movie-3:[
manufaturer(10),
producers(5),
actors(12)
],
movie-1:[
manufaturer(3),
producers(2),
actors(2)
],
movie-2:[
manufaturer(4),
producers(7),
actors(6)
],
]
below code gets all faceit fields from solr query from loop and adds into allFacetFields from each facetFieldIterator
List<FacetField> allFacetFields = new ArrayList<FacetField>();
for (Map.Entry<String, Integer> entry : coresResult.entrySet()) {
List<FacetField> coreFacets = respForCores.getFacetFields();
Iterator<FacetField> facetFieldIterator = coreFacets.iterator();
while(facetFieldIterator.hasNext()){
allFacetFields.add(facetFieldIterator.next());
}
}
how to validate duplicate faceit before adding it to final faceit field allFacetFields and merger the results as following :
[
movie-1:[
manufaturer(13),
producers(7),
actors(14)
],
movie-2:[
manufaturer(14),
producers(12),
actors(18)
],
movie-3:[
manufaturer(10),
producers(5),
actors(12)
]
]

Correct structure and query for Realtime Firebase Database

How can I structure my database in Firebase for search for recipes? Each recipe have some ingridients. I need to search for recipes. If the query contains several matching ingredients, I need to output a recipe containing a matching value.
It is my strucuture of database now :
{
"Recepts" : [ {
"Ingridients" : [ "Carrot", "Sugar" ],
"Name" : "Carrot Salad"
}, {
"Ingridients" : [ "Orange", "Milk" ],
"Name" : "Orange Milk"
} ]
}
If this is correct, how can I do a query for my database?
It is a best practice to avoid using array and save list of data as map instead.
To search for recipes having an ingredient, you could use orderByChild together with equalTo the ingredient you are looking for.
The data structure would be
{
"Recipes" : {
"CarrotSalad": {
"Ingredients" : {
"Carrot": true,
"Sugar": true
},
"Name" : "Carrot Salad"
},
....
}
}

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