How to add and remove elements in array in Mongo use Java? - java

So I have object:
"_id" : 1,
"employee_id" : [2, 3, 4, 5],
"project_name" : "qwerty"
And I want to delete from "employee_id" array [3, 5] and add new array [13, 6, 8]. And result will be:
"_id" : 1,
"employee_id" : [2, 4, 13, 6, 8],
"project_name" : "qwerty"
I use this Java-code:
DB database = mongoClient.getDB("employee_service");
DBCollection collectionProject = database.getCollection("project");
DBObject query = new BasicDBObject();
query.put("_id", project.getId());
DBObject projectMongoObject = new BasicDBObject();
projectMongoObject.put("project_name", project.getProjectName());
//something
collectionProject.update(query, projectMongoObject);
So how to set in projectMongoObject new array and delete array?

Make use of the $pullAll operator to remove the fields, and the combination of $push and $each to add new fields to the array.
DBObject query = new BasicDBObject();
query.put("_id", project.getId());
DBObject projectMongoObject = new BasicDBObject();
projectMongoObject.put("$set", new BasicDBObject("project_name",
project.getProjectName()));
projectMongoObject.put("$pullAll",
new BasicDBObject("employee_id", new int[]{3,5}));
collectionProject.update(query, projectMongoObject);
projectMongoObject = new BasicDBObject();
projectMongoObject.put("$push",
new BasicDBObject("employee_id",
new BasicDBObject("$each",
new int[]{13,6,8})));
collectionProject.update(query, projectMongoObject);

Related

Group by multiple fields in stream java 8

I have a class:
public class PublicationDTO {
final String publicationName;
final String publicationID;
final String locale;
final Integer views;
final Integer shares;
}
A need to get sum of views and shares. For test i created a list:
PublicationDTO publicationDTO1 = new PublicationDTO("Name1", "name1", "CA", 5, 6);
PublicationDTO publicationDTO2 = new PublicationDTO("Name2", "name2", "US", 6, 3);
PublicationDTO publicationDTO3 = new PublicationDTO("Name1", "name1", "CA", 10, 1);
PublicationDTO publicationDTO4 = new PublicationDTO("Name2", "name2", "CA", 2, 3);
List<PublicationDTO> publicationDTOS = List.of(publicationDTO1, publicationDTO2, publicationDTO3, publicationDTO4);
I want to group objects in list by publicationName, publicationId and locale and get result list like:
List.of(new PublicationDTO("Name1", "name1", "CA", 15, 7),
new PublicationDTO("Name2", "name2", "CA", 2, 3),
new PublicationDTO("Name2", "name2", "US", 6, 3));
I found a solution like:
List<PublicationDTO> collect = publicationDTOS.stream()
.collect(groupingBy(PublicationDTO::getPublicationID))
.values().stream()
.map(dtos -> dtos.stream()
.reduce((f1, f2) -> new PublicationDTO(f1.publicationName, f1.publicationID, f1.locale, f1.views + f2.views, f1.shares + f2.shares)))
.map(Optional::get)
.collect(toList());
but the result not grouped by locale and I'm not sure if it works by publicationId. Please let me know how to properly use collectors in such case?
You are only grouping by getPublicationID:
.collect(groupingBy(PublicationDTO::getPublicationID))
Since those fields you are interested in for grouping are all strings you could concatenate them and use that as a grouping classifier:
.collect(Collectors.groupingBy(p -> p.getPublicationName() + p.getPublicationID() + p.getLocale()))

How to convert list of map to array of hash

I am using Java for my application. Here is the my input data.
[{
"id": 1,
"firstname": "one",
"lastname": "1"
},
{
"id": 2,
"firstname": "two",
"lastname": "2"
},
{
"id": 3,
"firstname": "three",
"lastname": "3"
}
]
I want to convert the above input to like below output. How can I achieve the below output in an efficient manner?
{
["id", "firstname", "lastname"], [1, "one", "1"], [2, "two", "2"], [3, "three", "3"]
}
Update:
I have tried the below. But it resulted as below
Expected:
result => {[lastname, id, firstname]=[[1, 1, one], [2, 2, two], [3, 3, three]]}
Actual:
result => {[lastname, id, firstname], [1, 1, one], [2, 2, two], [3, 3, three]}
Code:
Map<String, Object> one = Map.of("id", 1, "firstname", "one", "lastname", "1");
Map<String, Object> two = Map.of("id", 2, "firstname", "two", "lastname", "2");
Map<String, Object> three = Map.of("id", 3, "firstname", "three", "lastname", "3");
ArrayList<Map<String,Object>> list = new ArrayList<>();
list.add(one);
list.add(two);
list.add(three);
MultiValueMap<Object, Object> result = new LinkedMultiValueMap<>();
Set<String> strings = list.get(0).keySet();
ArrayList<Object> objects = new ArrayList<>();
for(Map<String,Object> map: list) {
objects.add(map.values());
}
result.put(strings, objects);
The input JSON may be read into a list of maps data sharing the same key sets and this list is to be converted into a list of object arrays, with the first element of this list being the keys of a map.
So, at first the array of field names should be created, converted to Stream, and then merged with Stream<Object[]> retrieved from the values of each map in data list:
// using Jackson JSON to read the input
ObjectMapper mapper = new ObjectMapper();
String input = "[{\"id\":1, \"firstname\":\"First\", \"lastname\": \"Last\"}]";
List<Map<String, Object>> data = mapper.readValue(input, new TypeReference<>() {});
List<Object[]> output = Stream.concat(
Stream.<Object[]>of(data.get(0).keySet().toArray()),
data.stream().map(m -> m.values().toArray())
)
.collect(Collectors.toList());
System.out.printf("Result: {%n\t%s%n}%n",
output.stream().map(Arrays::toString).collect(Collectors.joining(", ")));
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(output));
Output:
Result: {
[id, firstname, lastname], [1, First, Last]
}
[ [ "id", "firstname", "lastname" ], [ 1, "First", "Last" ] ]
Or similarly the result could be a list of raw collections based on maps' keySet() and values, which could be created like this:
List<Collection> result = Stream.concat(
Stream.of(data.get(0).keySet()),
data.stream().map(Map::values)
).collect(Collectors.toList());

Java query code for mongodb query

Can Some one help toconvert this mongo query into java code ?
It works fine in mongo command line ,but I am not able run this with java .
Here is mongo query
db.booking.aggregate([{
"$match": {
"bookingDate": {
"$ne": null,
"$gte": new Date("2017-04-01"),
"$lte": new Date("2018-03-31")
}
}
},
{
"$project": {
"totalAmount": 1,
"totalPax": 1,
"month": {
"$month": {
$add: ["$bookingDate", 25200000]
}
}
}
},
{
"$group": {
"_id": "$month",
"totalPax": {
"$sum": "$totalPax"
},
"totalAmount": {
"$sum": "$totalAmount"
},
}
}
])
This is what I have tried , but its not working ,
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("bookingDate",
new BasicDBObject("$gte", OperationsUtil.getISODateFromUIDate(startDate)).append("$lte",OperationsUtil.getISODateFromUIDate(endDate)).append("$ne", null)));
BasicDBObject match1 = new BasicDBObject("$match", new BasicDBObject("bookingDeleted",false));
BasicDBList add=new BasicDBList();
add.add(new BasicDBObject("$bookingDate",25200000));
BasicDBObject monthDoc=new BasicDBObject("$add",add);
BasicDBObject project = new BasicDBObject("$project",new BasicDBObject("_id",0).append("totalAmount",1).append("totalPax",1).append("month",new BasicDBObject("$month",monthDoc)));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id","$month")
.append("totalPaxCount", new BasicDBObject("$sum", "$totalPax")).append("totalAmount",new BasicDBObject("$sum", "$totalAmount")));
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
AggregationOutput cursor = bookingCollection.aggregate(match,match1,project,group,sort);
we were able to convert the above query solution , here is the code for the above query , just answering so that if someone come across this kind problem can refer this answer
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("bookingDate",
new BasicDBObject("$gte", OperationsUtil.getISODateFromUIDate(startDate)).append("$lte",OperationsUtil.getISODateFromUIDate(endDate)).append("$ne", null)));
BasicDBObject match1 = new BasicDBObject("$match", new BasicDBObject("bookingDeleted",false).append("tour.travelStatus",new BasicDBObject("$ne", "Unreceipted")));
BasicDBList addition=new BasicDBList();
addition.add("$bookingDate");
addition.add(OperationsConstant.UTC_TO_IST_MILLISECONDS);
BasicDBObject monthDoc=new BasicDBObject("$add",addition);
BasicDBObject project = new BasicDBObject("$project",new BasicDBObject("_id",0).append("totalAmount",1).append("totalPax",1).append("month",new BasicDBObject("$month",monthDoc)));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id","$month")
.append("totalPaxCount", new BasicDBObject("$sum", "$totalPax")).append("totalAmount",new BasicDBObject("$sum", "$totalAmount")));
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
AggregationOutput cursor = bookingCollection.aggregate(match,match1,project,group,sort);

Pairs insertion/retrieval in/from field

I am trying to insert pairs in a mongoDB Document. This how i am doing it so far:
private static MongoCollection<Document> getCollectionn(String link, String coll){
...
}
public static void main(String[] args) {
MongoCollection<Document> fb_users;
fb_users = getCollectionn("mongodb://...", "fb_users2");
Document myDoc;
BasicDBObject query = new BasicDBObject();
query.put("fbid", "1");
myDoc = fb_users.find(query).first();
int postId=5;
int rating=3;
fb_users.updateOne(myDoc,
new Document("$push", new Document("ratings", java.util.Arrays.asList(rating, postId))));
Object a = myDoc.get("ratings");
ArrayList<Document> b = (ArrayList<Document>) a;
System.out.println(b.get(0);//prints [3, 5]
}
This is how the array document is inserted in the collection after two runs:
(the document already exists)
{
"_id": {
"$oid": "56f173b5e4b04eaac6531030"
},
"fbid": "1",
"ratings": [
[
3,
5
],
[
3,
5
]
]
}
In println i get the result [3, 5]
My question is this:
How can i recieve the numder 3 and the number 5 seperatly? Should i insert the documents with another way? Iam using mongo java driver 3.2.0.
Ok i found the solution. Here it is:
Document myDoc;
BasicDBObject query = new BasicDBObject();
query.put("fbid", "1");
myDoc = fb_users.find(query).first();
int postId=5;
int rating=3;
Document listItem = new Document("ratings", new Document(String.valueOf(rating), String.valueOf(postId)));
Document updateQuery = new Document("$push", listItem);
fb_users.updateOne(myDoc, updateQuery);
MongoCursor<Document> curs = fb_users.find(query).iterator();
ArrayList<Document> list = (ArrayList<Document>) myDoc.get("ratings");
Iterator<Document> iterateList = list .iterator();
while(iterateList .hasNext()){
Document pair = iterateList .next();
for(String element : pair.keySet()){
System.out.println(element + " " + pair.get(element));
}
}
and the json format is and should be like this:
{
"_id": {
"$oid": "56f173b5e4b04eaac6531030"
},
"fbid": "1",
"ratings": [
{
"3": "5"
},
{
"3": "5"
}
]
}

Mongodb query for nested document in java

I am new to Mongodb. I have the following dataset in mongodb.
{
"_id": {
"$oid": "563644f44b17ca12886440a9"
},
"data": [
{
"uid": 1,
"character": " ",
"unicode": 32,
"color": -7309587
},
{
"uid": 2,
"character": "!",
"unicode": 33,
"color": -8911704
},
{
"uid": 3,
"character": "\"",
"unicode": 34,
"color": -1778539
}
I am trying to retrieve the color from this field using the _id and character. I am not able to execute the query.
This is what I tried.
DBObject clause1 = new BasicDBObject("_id",new ObjectId(KEY1));
DBObject clause2 = new BasicDBObject("data.character",text[i]);
BasicDBList or = new BasicDBList();
or.add(clause1);
or.add(clause2);
DBObject query = new BasicDBObject("$and", or);
Also I am having a lot of issues in finding ways to query in mongodb-java for the 3.0.0+ api. Could someone please help?
MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017));
MongoDatabase db = mongoClient.getDatabase("testDB");
AggregateIterable<Document> iterable = db.getCollection("testCollection").aggregate(
asList(new Document("$unwind", "$data"), new Document("$match", (new Document("_id", new ObjectId(
"5636f106b2acf98ecb033b98")).append("data.character", " "))), new Document("$project",
new Document("data.color", 1).append("_id", 0))));
iterable.forEach(new Block<Document>()
{
#Override
public void apply(final Document document)
{
System.out.println(document.toJson());
}
});
For more details check MongoDB Documentation.
A simple solution
In your document,
oid is an unique key for each document and hence your query should be like this
DBObject query = new BasicDBObject("_id.oid", KEY1);
// Query with value - DBObject query = new BasicDBObject("_id.oid","563644f44b17ca12886440a9");
Assign this to a cursor as shown below
DBCollection coll = db.getCollection("mycollection");
DBCursor cursor = coll.find(query);
Iterate the collection and retrieve your desired value.

Categories

Resources