Run an aggregation using Java Driver - MongoDB - java

Using MongoDB shell I use:
db.bios.aggregate(
[
{$match:{"contribs.0.name":{"$exists":1}}},
{$project: {contribs:{$arrayElemAt:["$contribs",0]}}}
]
)
How can I make the same query using Java driver (2.14.1)?
I try with:
At first I create a DBObject for $match stage:
DBObject match = new BasicDBObject("$match",new BasicDBObject("contribs.0.name",
new BasicDBObject("$exists",1)));
Then I create a BasicDBList:
BasicDBObject obj = new BasicDBObject("$contribs",0);
BasicDBList arrayElemAt = new BasicDBList();
arrayElemAt.add(obj);
And this is the $project stage:
DBObject project1 = new BasicDBObject("$project", new BasicDBObject("contribs",
new BasicDBObject("$arrayElemAt",arrayElemAt)));
Finally I create the aggregation pipeline:
List<DBObject> list = new ArrayList<>();
list.add(match);
list.add(project1);
AggregationOutput output = this.coll.aggregate(list);
$Match stage works, but $project does not.
I get an error: "errmsg" : "invalid operator '$contribs'" , "code" : 15999

You created a DBObject when you were meant to create a List. Also DBList has been deprecated for a while now. Get used to using standard list notations:
List<DBObject> pipeline = Arrays.<DBObject>asList(
new BasicDBObject(
"$match",
new BasicDBObject(
"contribs.0", new BasicDBObject("$exists",true)
)
),
new BasicDBObject(
"$project",
new BasicDBObject(
"contribs", new BasicDBObject("$arrayElemAt", Arrays.asList("$contribs",0))
)
)
);
AggregationOutput output = this.coll.aggrgate(pipeline);
Also note that in modern drivers you really should be using Document in place of all DBObject types.

Related

How to write Java code for the following mongo query using mongoTemplate?

Query in shell window is as follows:
db.labServiceMasters.aggregate(
{$unwind: '$subDepartmentList'},
{$unwind: '$subDepartmentList.labServiceList'},
{$match: {'subDepartmentList.labServiceList._id': '123def'}},
{$project: {_id: 1, labServiceList: ['$subDepartmentList.labServiceList']}}
)
I have converted the above query to Java code as shown below, but I am not getting the result inside labServiceList. And also please let me know how to read the result as my POJO object.
DBObject unwind1 = new BasicDBObject("$unwind" , "$subDepartmentList");
DBObject unwind2 = new BasicDBObject("$unwind" , "$subDepartmentList.labServiceList");
DBObject match = new BasicDBObject("$match", new BasicDBObject("subDepartmentList.labServiceList._id", labServiceId));
DBObject project = new BasicDBObject("$project", new BasicDBObject("_id",1).append("subDepartmentList.labServiceList", 1));
AggregationOutput output=mongoTemplate.getCollection(laboratoryMasterCollection).aggregate(unwind1, unwind2, match, project);
List<DBObject> results = (List<DBObject>) output.results();
for(DBObject response: results){
System.out.println("INside for each loop of Results");
Master master=(Master) response;
System.out.println("master:: "+response.getDepartmentId());
}

Transforming MongoDB query to Java with $elemMatch

I'm having a lot of trouble transforming my MongoDB Query into a Java one.
I've tried both QueryBuilder and DBObject and can't manage to make it work.
This is my MongoDB Query:
db.getCollection('myCollection_v2').find({
idCab:1,
cab: {
$elemMatch:{
idCat: ObjectId("14567823123688")
}
},
fMod: {
$gte: ISODate("2017-04-04T00:00:000Z"),
$lt: ISODate("2017-04-04T23:59:590Z")
}
})
My DBOBject approach has been this and the problem that I get is that I cannot append(object, object) but append(string, object) so I don't know how should I structure it:
BasicDBObject query = new BasicDBObject(
"idCab", "1")
.append( new BasicDBObject(
"cab", new BasicDBObject(
"$elemMatch", new BasicDBObject(
"idCat", categoria ))))
.append( new BasicDBObject(
"fMod", new BasicDBObject( "$gte", fechaInicio )
.append( "$lt", fechaFin )
)
);
For a QueryBuilder I have this and the problem is that I didn't manage to make the part about the $elemMatch...
QueryBuilder query = new QueryBuilder().start().and(
new QueryBuilder().start().put("idCab").is(String.valueOf(pIdPortal)).get(),
new QueryBuilder().start().put("fMod")
.greaterThan(fechaInicio).get(),
new QueryBuilder().start().put("fMod")
.lessThan(fechaFin).get();
Could you help me, please? I'm going from a 50-50 love/hate relationship with MongoDB to a 100 hate relationship...
your DBObject is not properly formed. Your trying to pass a BasicDBObject as key instead of passing a String .
Just remove the two extra BasicDBObject like this :
BasicDBObject query = new BasicDBObject(
"idCab", 1)
.append("cab", new BasicDBObject(
"$elemMatch", new BasicDBObject(
"idCat", categoria)))
.append("fMod", new BasicDBObject("$gte", fechaInicio)
.append("$lt", fechaFin)
);

exception: FieldPath 'C6' doesn't start with $" in mongo Java

I am working on Mongodb by using Java. In that I am trying to select certain record under some conditions including group by. The code I have used is as follows.
DBObject wherequery = new BasciDBOBject();
wherequery.put("deviceID", C6);
wherequery.put("reqTime", new BasicDBObject(
"$lt", sometime)
.append("$gt", someothertime));
DBObject project = new BasicDBObject("$project",
wherequery);
DBObject groupFields = new BasicDBObject("_id",
"$requestID");
DBObject group = new BasicDBObject("$group", groupFields);
AggregationOutput output = collection.aggregate(project, group);
when I run this code, I am getting following error:
exception: FieldPath 'C6' doesn't start with $"
what this error means? It denotes deviceID C6 that I have used. what I am missing or how am I wrong?
please help me out
If you want to select documents that match specified condition, you should use $match operator for your first pipline stage, not $project.
Add your wherequery to $match and for project used different DBObject check code as below :
DBObject wherequery = new BasciDBOBject();
wherequery.put("deviceID",C6 );
wherequery.put("reqTime", new BasicDBObject(
"$lt", sometime)
.append("$gt", someothertime));
DBObject match = new BasicDBObject("$match",
wherequery);
DBObject groupFields = new BasicDBObject("_id",
"$requestID");
DBObject group = new BasicDBObject("$group", groupFields);
//for projecting data
DBObject projectData = new BasciDBOBject();
projectData.put("deviceID", "$deviceID"); // projectData.put("deviceID", 1); this also work
projectData.put("reqTime", "$reqTime");
DBObject project = new BasicDBObject("$project",
projectData);
AggregationOutput output = collection.aggregate(match, group,project);
For more check this Mongo Java driver for aggregation

How to use aggregation in Mongo db Java driver with $match and $in?

How to convert below query into Java code for Mongo Java driver?
db.post.aggregate(
[
{ $match : {"name" :{'$in': ["michael", "jordan"] } }},
{ $group : { _id : "$game.id" , count : { $sum : 1 } } }
]
)
My function is not working:
DBObject match = new BasicDBObject('$match', new BasicDBObject("name", names));
The $in operator takes and array or list of arguments, so any list will basically do. But you need to form the corresponding BSON. Indenting your code helps to visualize:
BasicDBList inArgs = new BasicDBList();
inArgs.add("michael");
inArgs.add("jordan");
DBObject match = new BasicDBObject("$match",
new BasicDBObject("name",
new BasicDBObject("$in", inArgs )
)
);
DBObject group = new BasicDBObject("$group",
new BasicDBObject("_id","$game.id").append(
"count", new BasicDBObject("$sum",1)
)
);
According to the Aggregation Documentation, your query should look like:
DBObject match = new BasicDBObject('$match', new BasicDBObject('name', new BasicDBObject('$in', names)));

How to perform match on sum of two fields

I have a query in MySQL that contains the following condition:
WHERE START_TIME < ? AND START_TIME+DURATION >= ?
How should I migrate this to MongoDB using Java driver and aggregation framework?
The first condition will become:
DBObject match = new BasicDBObject("$match", new BasicDBObject("start_time", "{ $lt : "+timestamp+"}") );
But I'm not sure about the second.
Thanks.
EDIT
I've tried to work with Asya Kamsky answer, this is what I got but it's not working:
BasicDBList dbList = new BasicDBList();
dbList.add("$start_time");
dbList.add("$duration");
DBObject matchLT = new BasicDBObject("$match", new BasicDBObject("start_time", new BasicDBObject("$lt",timestamp)));
DBObject project = new BasicDBObject("$project", new BasicDBObject("end_time", new BasicDBObject("$add", dbList)));
DBObject matchGTE = new BasicDBObject("$match", new BasicDBObject("end_time", new BasicDBObject("$gte",timestamp)));
//GROUP CODE GOES HERE
AggregationOutput output = collection.aggregate(matchLT, project, matchGTE, group);
Here's how you do it in Aggregation Framework, I'm sure you can translate this to Java:
db.collection.aggregate([ {$match: {start_time:{$lt:ISODate("xxxx-xx-xx")}}},
{$project:{end_time:{$add:["$start_time","$duration"]}}},
{$match:{end_time:{$gt:ISODate("yyyy-yy-yy")}}}
] );

Categories

Resources