I need to rename one field in document - java

Here is the code :
AggregateIterable<Document> result = chatLogCollection.aggregate(Arrays.asList(
new Document("$match", new Document("displayName", "user")),
new Document("$group", new Document("_id","$sessionGUID")
.append("time", new Document("$first","$ts"))
.append("makerID", new Document("$first","$makerID"))),
new Document("$sort", new Document("time", -1)),
new Document("$skip", skip),
new Document("$limit", limit)
));
This will generate the below type out put.
{
"displayName": "test test",
"_id": "123a54be-4b69-cd49-edb3-9b264fea077b",
"time": {
"$date": 1499759619016
},
"makerID": "xxxxx"
}
I need to format this to look like this:
{
"displayName": "test test",
"sessionID": "123a54be-4b69-cd49-edb3-9b264fea077b",
"time": {
"$date": 1499759619016
},
"makerID": "xxxxx"
}
That means i need to appear _id as sessionId. Please help me to do that.I am using mongoDB, java and windows 7.

Related

Project using array fields in MongoDB Java Driver

I have Collection as following. I have query this collection by user.
{
"user": "username",
"sites": {
"site": "abc",
"keywords": [
{
"keyword": "keyword1",
"dailyranks": [
{
"fild1": "value1"
},
{
"fild2": "value2"
},
{
"fild3": "value3"
},
]
},
{
"keyword": "keyword2",
"dailyranks": [
{
"fild1": "value1"
},
{
"fild2": "value2"
},
{
"fild3": "value3"
},
]
},
],
}
}
I want to get the result from the collection as follows, I want to get the last elements of keyword array in the collection
[
{
"keyword" : "keyword1"
"fild2" : "value2",
"fild3" : "value3"
},
{
"keyword" : "keyword2"
"fild2" : "value2",
"fild3" : "value3"
},
]
I have aggregate using $project, but didn't work out. help me to sort this out.
Code used-
BasicDBObject siteObject = new BasicDBObject();
siteObject.append("keywords", "$sites.keywords.keyword");
siteObject.append("lastrank", "$sites.keywords.dailyranks");
BasicDBList aDBList = new BasicDBList();
aaa.add(new BasicDBObject("user", modelLogin.getUSER_NAME()));
ArrayList<BasicDBObject> doc = new ArrayList<>();
doc.add(new BasicDBObject().append("$unwind", "$sites"));
doc.add(new BasicDBObject("$match", aDBList));
doc.add(new BasicDBObject().append("$project", siteObject));
AggregationOutput output = coll.aggregate(doc);
You can try below aggregation.
Use $map to transform the Keywords array.
Within $map, use $arrayElemAt to project the last and second last values from dailyranks and $let operator to hold the result from $arrayAtElem and project the fild value.
db.coll.aggregate({
$project: {
keywords: {
$map: {
input: "$sites.keywords",
as: "result",
in: {
keyword: "$$result.keyword",
fild2: {$let: {vars: {obj: {$arrayElemAt: ["$$result.dailyranks", -2]}},in: "$$obj.fild2"}},
fild3: {$let: {vars: {obj: {$arrayElemAt: ["$$result.dailyranks", -1]}},in: "$$obj.fild3"}}
}
}
}
}
})
Java Equivalent
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("db")
MongoCollection<Document> collection = db.getCollection("collection");
List<Document> results =
collection.aggregate(
Arrays.asList(
Aggregates.match(Filters.eq("user", modelLogin.getUSER_NAME() )),
Aggregates.project(
Projections.fields(
new Document("keywords",
new Document("$map",
new Document("input", "$sites.keywords").
append("as", "result").
append("in",
new Document("keyword","$$result.keyword").
append("fild2",
new Document("$let",
new Document("vars", new Document("obj",
new Document("$arrayElemAt", Arrays.asList("$$result.dailyranks", -2)))).
append("in", "$$obj.fild2" ))).
append("fild3",
new Document("$let",
new Document("vars", new Document("obj",
new Document("$arrayElemAt", Arrays.asList("$$result.dailyranks", -1)))).
append("in", "$$obj.fild3" )))
)
)
)))
)).into(new ArrayList<>());

Add field to subdocument from document returned from query

I want to add a field to the returned subdocument like this:
{
"type": "product",
"code": "abc",
"team": "A1",
"modules": [{
"type": "module",
"code": "cde"
//Add a new field here
}]
}
I can add new field in document by Document.append() but can't add to the subdocument.
Here is my Java code:
BasicDBObject query = new BasicDBObject("code", "abc");
AggregateIterable<Document> findIterable = collection.aggregate(Arrays.asList(
new Document("$match", query),
new Document("$project", new Document("_id", 0).append("type", 1)
.append("code", 1)
.append("team", 1)
.append("modules", 1)
),
new Document("$sort", new Document("code", 1))
));
mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
Document document = mongoCursor.next();
}
Can someone give some help please? Thanks a lot in advance!!!

Jackson converting dynamic json to map

I have a problem where some structure of the json is fixed while some part is dynamic. The end output has to be an object of type
Map<String,List<Map<String,String>>>
I am pasting a sample json code for which the jackson work -
{
"contentlets": [
{
"template": "8f8fab8e-0955-49e1-a2ed-ff45e3296aa8",
"modDate": "2017-01-06 13:13:20.0",
"cachettl": "0",
"title": "New Early Warnings",
"subscribeToListIi": "am#zz.com",
"inode": "15bd497-1d8e-4bc7-b0f4-c799ed89fdc9",
"privacySetting": "public",
"__DOTNAME__": "New gTLD Early Warnings",
"activityStatus": "Completed",
"host": "10b6f94a-7671-4e08-9f4b-27bca80702e7",
"languageId": 1,
"createNotification": false,
"folder": "951ff45c-e844-40d4-904f-92b0d2cd0c3c",
"sortOrder": 0,
"modUser": "dotcms.org.2897"
}
]
}
ObjectMapper mapper = new ObjectMapper();
Map<String,List<Map<String,String>>> myMap=mapper.readValue(responseStr.getBytes(), new TypeReference<HashMap<String,List<Map<String,String>>>>() {});
The above code is working fine but when the json changes to (basically a metadata tag is added) it is not able to convert to map.
{
"contentlets": [
{
"template": "8f8fab8e-0955-49e1-a2ed-ff45e3296aa8",
"modDate": "2017-01-06 13:13:20.0",
"cachettl": "0",
"title": "New gTLD Early Warnings",
"subscribeToListIi": "aml#bb.com",
"inode": "15bd4057-1d8e-4bc7-b0f4-c799ed89fdc9",
"metadata": {
"author": "jack",
"location": "LA"
},
"privacySetting": "public",
"__DOTNAME__": "New gTLD Early Warnings",
"activityStatus": "Completed",
"host": "10b6f94a-7671-4e08-9f4b-27bca80702e7",
"languageId": 1,
"createNotification": false,
"folder": "951ff45c-e844-40d4-904f-92b0d2cd0c3c",
"sortOrder": 0,
"modUser": "dotcms.org.2897"
}
]
}
This is expected since the type of the value of metadata is not a String. If you change the type of the map accordingly then it works:
Map<String,List<Map<String,Object>>> myMap = mapper.readValue(reader, new TypeReference<HashMap<String,List<Map<String,Object>>>>() {});
Of course you are left with the problem that values in the map are not of the same type. so you need to ask yourself what is the desired data structure you want and how you further process it. However, one cannot deserialize a json structure into a simple String.

Java mongodb - find then average

Okey, let's start. Imagine that we have the next mongo collection:
{
"city": "TWENTYNINE PALMS",
"loc": [-116.06041, 34.237969],
"pop": 11412,
"state": "CA",
"_id": "92278"
}
{
"city": "NEW CUYAMA",
"loc": [-74.823806, 34.996709],
"pop": 80,
"state": "CA",
"_id": "93254"
}
{
"city": "WATERBURY",
"loc": [-72.996268, 41.550328],
"pop": 25128,
"state": "CT",
"_id": "06705"
}
Notice that loc array is [latitude,longitude]
I would like to obtain using java mongo driver the "pop" average of the cities that have the altitude beetwen -75,-70.
So, using SQL I know that the query is:
SELECT avg(pop)
WHERE loc.altitude > -75 AND lloc.altitude < -70
I am very noob in mongodb, this is my current code:
BasicDBObject doc = new BasicDBObject("loc.0", new BasicDBObject("$gte",
-75).append("$lte", -70));
DBCursor cursor = collection.find(doc);
The previous code returns me all the documents that altitude are beetwen (-75,-70), but I do not know how to obtain the average,using mongo driver, I know that I can iterate over results using java..
Thank you
Use the aggregation framework with following aggregation pipeline (Mongo shell implementation):
db.collection.aggregate([
{
"$match": {
"loc.0": { "$gte": -75 },
"loc.1": { "$lte": 70 }
}
},
{
"$group": {
"_id": 0,
"average": {
"$avg": "$pop"
}
}
}
])
With the example above, this outputs to console:
/* 1 */
{
"result" : [
{
"_id" : 0,
"average" : 12604
}
],
"ok" : 1
}
With Java, this can be implemented as follows:
DBObject match = new BasicDBObject();
match.put("loc.0", new BasicDBObject("$gte", -75));
match.put("loc.1", new BasicDBObject("$lte", 70));
DBObject groupFields = new BasicDBObject( "_id", 0);
groupFields.put("average", new BasicDBObject( "$avg", "$pop"));
DBObject group = new BasicDBObject("$group", groupFields);
AggregationOutput output = collection.aggregate( match, group );

Generate JSON in JAVA

I want generate under JSON code in Java:
{
"rowsPerPage": 10,
"page": 1,
"total": 100,
"rows": [
{
"id": 1,
"name": "name1"
},
{
"id": 2,
"name": "name2"
},
{
"id": 3,
"name": "name3"
}
]
}
I know how generate rowsPerPage, page and total, but I don't know how generate rows?
ModelMap modelMap = new ModelMap();
modelMap.put("rowsPerPage", 10);
modelMap.put("page", 1);
modelMap.put("total", 100);
Essentially, you want something like this:
ModelMap [] rowMap = new ModelMap()[3];
for (int i=0;i<3;i++)
{
ModelMap this_row=new ModelMap();
this_row.put("id",i);
this_row.put("name","name"+i);
rowMap(i)=this_row;
}
modelMap.put("rows",rowMap);
This might need to be adjusted to meet your needs, but it should at least show you how to do it.
put each row contents in a map
for(Row row :rows){
HashMap map = new HashMap();
map.put("id",row.getId());
map.put("name",row.getName());
jsonObj.append("rows", map);
}
You should use a JSON tool like Google's GSON: http://code.google.com/p/google-gson/

Categories