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
Related
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());
}
I am trying to aggregate values based on group by, match and sort. However, my matching field type is ObjectId. I have an input parameter which is a type of ObjectId(ObjectId settingId), however, below code does not return anything.
Can anyone find the problem in my code?
AggregateIterable < Document > iterable = thermalComfortCollection.aggregate(Arrays.asList(
new Document("$group", new Document("_id", "$Timestamp").append("ThermalComfortList", new Document("$push", "$ThermalComfort"))),
new Document("$match", new Document("settingID", settingId)),
new Document("$sort", new Document("_id", 1))));
You doing a group on the first stage, print that result to check if there's a "settingID" field on the top level.
From you $group stage it seems like the output will be:
[
{
_id : value of $Timestamp,
ThermalComfortList : []},
...
]
When posisble do the $match stage before the $group stage. $match is then able to use the (i hope available) index on settingID
You can use the BasicDBObject as follows:
DBObject match = new BasicDBObject("$match", new BasicDBObject("settingID", new ObjectId("")));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id", "$Timestamp").append("ThermalComfortList", new BasicDBObject("$push", "$ThermalComfort")));
DBObject group = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
List<DBObject> aggregateList = new ArrayList<DBObject>();
aggregateList.add(match11);
aggregateList.add(group11);
aggregateList.add(group11);
AggregationOutput result = collection.aggregate(aggregateList);
I have tried searching on internet about this error, but nothing helped. I am trying to use aggregate function in mongodb using Java. RetailerZip is the field I want to group my result.
groupFields = new BasicDBObject("_id", 0);
groupFields.put("count",new BasicDBObject("$sum",1));
groupFields.put("_id", "$RetailerZip");
group = new BasicDBObject("$group", groupFields);
sort = new BasicDBObject();
projectFields = new BasicDBObject("_id", 0);
projectFields.put("value", "$_id");
projectFields.put("ReviewValue","$count");
project = new BasicDBObject("$project", projectFields);
sort.put("ReviewValue",-1);
orderby=new BasicDBObject("$sort",sort);
limit=new BasicDBObject("$limit",5);
List<DBObject> pipeline = Arrays.asList(group, project, orderby, limit); //error occurs on this line.
AggregationOutput output = mongo.myReviews.aggregate(pipeline);
MongoDB version installed is: 3.2.11
you put "_id" twice in your $group stage.
try to replace this
groupFields = new BasicDBObject("_id", 0);
groupFields.put("count",new BasicDBObject("$sum",1));
groupFields.put("_id", "$RetailerZip");
by
groupFields = new BasicDBObject("_id", "$RetailerZip");
groupFields.put("count",new BasicDBObject("$sum",1));
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.
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")}}}
] );