I want to write this query in mongo-
select account, count(*) from OBD_active group by account;
I am writing code in java-
DBObject match = new BasicDBObject("$match", new BasicDBObject() );
DBObject fields = new BasicDBObject("account", 1);
fields.put("status", 1);
fields.put("_id", 0);
DBObject project = new BasicDBObject("$project", fields );
DBObject groupFields = new BasicDBObject( "count", "$account");
groupFields.put("total", new BasicDBObject( "$sum", "$status"));
DBObject group = new BasicDBObject("$group", groupFields);
db = Connect.getConnection();
coll = collection(db, "OBD_active");
AggregationOutput output = coll.aggregate( match, project, group );
System.out.println("Output is"+output);
and getting output-
Output is{ "serverUsed" : "localhost/127.0.0.1:27017" , "result" : [ { "_id" : "relnew" , "total" : 3.0} , { "_id" : "tata" , "total" : 2.0}] , "ok" : 1.0}
Result is Ok but I want to iterate this result, how to achieve this ?
The MongoDB javadoc gives the answer: AggregationOutput has a .results() method which returns an Iterable over the results.
And Iterable "means" usage in a foreach loop is possible. As such:
for (final DBObject result: output.results())
// do something with the result
Related
I want to parse a java string to mongo DBObject or BasicDBObject as below.
List<DBObject> query = new ArrayList<DBObject>();
String allQry = "{ \"$match\" : { \"CUSTOMERID\" : { \"$gt\" : 10}}}, { \"$project\" : { \"CUSTOMERNAME\" : 1 , \"COUNTRY\" : 1 , \"CUSTOMERID\" : 1}},{ \"$sort\" : { \"COUNTRY\" : 1}}";
BasicDBObject dbobj = BasicDBObject.parse(allQry);
query.add(dbobj);
System.out.println("qqqquery : "+query);
Cursor aggCur = collection.aggregate(query, aggOpt);
After run above example codes, it outputs qqqquery : [{ "$match" : { "CUSTOMERID" : { "$gt" : 10}}}]. There are $match , $project and $sort in allQry. Why do not it includes $project and $sort in this query? It only includes $match, who can help to check this reason? Thanks.
Following this tutorial:
http://pingax.com/trick-convert-mongo-shell-query-equivalent-java-objects/
you could add all parts of your query like this:
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("pingax");
DBCollection coll = db.getCollection("aggregationExample");
/*
MONGO SHELL : db.aggregationExample.aggregate(
{$match : {type : "local"}} ,
{$project : { department : 1 , amount : 1 }}
);
*/
DBObject match = new BasicDBObject("$match", new BasicDBObject("type", "local"));
DBObject project = new BasicDBObject("$project", new BasicDBObject("department", 1).append("amount", 1));
AggregationOutput output = coll.aggregate(match,project,group,sort);
Related:
How to find documents matching multiple criteria
Executing Mongo like Query (JSON)through Java
when i use this query on mongo shell
db.matchgrup.aggregate([{$match:{ "longitude" : {"$gte":73.8172198689148,"$lte":73.8200133489148}, "latitude" :{"$gte":19.98591316489416,"$lte":19.98870664489416} }},{ "$group": {"_id":null, "band_4" : { "$avg" : "$band_4"},"band_8":{"$avg":"$band_8"} } }])
it return
{ "_id" : null, "band_4" : 1578.8266666666666, "band_8" : 2649.0155555555557 }
but when i used mongo java driver for same query
searchQuery1 =new BasicDBObject("longitude", new BasicDBObject("$gte", X.doubleValue()).append("$lte", px1.doubleValue()));
criteria.add(searchQuery1);
searchQuery2=new BasicDBObject("latitude", new BasicDBObject("$gte", py2.doubleValue()).append("$lte", Y.doubleValue() ));
criteria.add(searchQuery2);
query2=new BasicDBObject("$and",criteria);
group1 = new BasicDBObject();
group1.put("_id", null);
group1.put("band_4", new BasicDBObject("$avg", "$band_4"));
group1.put("band_8", new BasicDBObject("$avg", "$band_8"));
output = coll.aggregate(
new BasicDBObject("$match",query2),
new BasicDBObject("$group",group1));
for (DBObject doc : output.results()) {
band4=(Double)doc.get("band_4");
band8=(Double)doc.get("band_8");
}
and it doesn't retuen any value and doesnt goes inside of for loop of doc
can anybody help me out what m doing wrong
I have a little problem with MongoDB, I'm trying to create a query with multiple operators with the Java driver. I'm looking for something like this :
x1 : y1 OR (x2 : y2 AND x3 : y3)
At the moment I have this :
BasicDBObject andQuery = new BasicDBObject();
List<BasicDBObject> obj2 = new ArrayList<BasicDBObject>();
obj2.add(new BasicDBObject("x1", "y1"));
andQuery.put("$or", obj2);
List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
obj.add(new BasicDBObject("x2", "y2"));
obj.add(new BasicDBObject("x3", "y3"));
andQuery.put("$and", obj);
And that give me this when I make a print :
{ "$or" : [ { "x1" : "x1"}] , "$and" : [ { "x2" : "x2"} , { "x3" : "y3"}]}
So I think the problem comes from the first ']' which should be at the end, so the $and will be in the $or array.
But how can I make this possible ? Thanks !
Try this :
BasicDBObject orQuery = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
obj.add(new BasicDBObject("x2", "y2"));
obj.add(new BasicDBObject("x3", "y3"));
andQuery.put("$and", obj);
List<BasicDBObject> obj2 = new ArrayList<BasicDBObject>();
obj2.add(new BasicDBObject("x1", "y1"));
obj2.add(andQuery);
orQuery.put("$or", obj2);
In the following query , I'm doing addition to a field (This field having ISO date as value) then extracting hour from that field, then group by on hour
db.campaigns.aggregate([
{$group : { _id: {$hour:{$add:['$time', 19800000]}}}}
])
Sample record of the collection
db.campaigns.findOne()
{
"_id" : ObjectId("53c7afdab92be74745af9068"),
"time" : ISODate("2013-03-08T12:25:24.973Z"),
"type" : "annoying",
"PINGS" : 143
}
The above one is working fine in Mongo shell,
I'm trying write this query in Java
Here is my partial Java code
DBObject group2Fields = new BasicDBObject();
group2Fields.put("hour", new BasicDBObject("$hour", new BasicDBObject("$add",new BasicDBObject("time",19800000))));
DBObject group2 = new BasicDBObject("_id", group2Fields);
DBObject secondGroup = new BasicDBObject("$group", group2);
I'm getting "errmsg" : "exception: field inclusion is not allowed inside of $expressions"
try this:
DBObject group2Fields = new BasicDBObject();
BasicDBList addObjects = new BasicDBList();
addObjects.add("$time");
addObjects.add(19800000);
group2Fields.put("$hour", new BasicDBObject("$add", addObjects));
DBObject group2 = new BasicDBObject("_id", group2Fields);
DBObject secondGroup = new BasicDBObject("$group", group2);
Nesting calls in your code generally helps you to "visualise" the structure that you want:
BasicDBList addArgs = new BasicDBList();
addArgs.add("$time");
addArgs.add(19800000);
DBObject group = new BasicDBObject("$group",
new BasicDBObject("_id",
new BasicDBObject("$hour",
new BasicDBObject("$add", addArgs)
)
)
);
Which of course produces a group variable that serializes like so:
{ "$group" : { "_id" : { "$hour" : { "$add" : [ "$time" , 19800000]}}}}
I need to implement "Popular Keyword" in my web app so that most searched keywords will show there.. For that i have created a db in mongo. I need to retrieve data from mongo so that mostly occuring keywords should sort and should return to my page. In sql it is just like as,
select names,count(names) from keyword_db group by names order by names;
need both java code and mongo shell query..
You might want to try for the mongo shell query (I'm sorting in descending order:
db.keyword_db.aggregate ( [
{ $group: { _id: "$names", count: { $sum: 1 } } },
{ $sort: { count: -1 } } ] )
For the Java version:
DBCollection myColl = db.getCollection("keyword_db");
// for the $group operator
DBObject groupFields = new BasicDBObject( "_id", "$names");
groupFields.put("count", new BasicDBObject( "$sum", 1));
DBObject group = new BasicDBObject("$group", groupFields );
// for the $sort operator
DBObject sortFields = new BasicDBObject("count", -1);
DBObject sort = new BasicDBObject("$sort", sortFields );
// run the aggregation
AggregationOutput output = myColl.aggregate(group, sort);
System.out.println( output.getCommandResult() );
The following page may help you also:
http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/
For sorting you can use following..1 for ascending and -1 for desc.
db.keyword_db.find( { names: "A" } ).sort( { user_id: 1 } )
and for groupBy You can use Aggregation framework..
http://docs.mongodb.org/manual/reference/method/db.collection.group/