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]}}}}
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 am trying to create this query from Java for MongoDB.
Do you know how can I construct it in java?
db.node.find({
connectedWithIds: { $in: [
ObjectId('56bca32fe74a987ad8724da1')
] }
})
I tried to use this:
ObjectId arr[] = {new ObjectId("5409ae2e2cdc31c5aa0ce0a5")};
BasicDBObject inQuery = new BasicDBObject("$in", arr);
BasicDBObject query = new BasicDBObject("connectedWithIds", inQuery);
but the results is below:
{ "connectedWithIds" : { "$in" : [ { "$oid" : "5409ae2e2cdc31c5aa0ce0a5"}]}}
and occurs this error:
error: {
"$err" : "Can't canonicalize query: BadValue cannot nest $ under $in",
"code" : 17287
}
I could overcome this error with the code below:
ArrayList<ObjectId> vals = new ArrayList<ObjectId>();
vals.add(objectId);
BasicDBObject inQuery = new BasicDBObject("$in", vals);
BasicDBObject query = new BasicDBObject("connectedWithIds", inQuery);
List<BasicDBObject> users = (List<BasicDBObject>) customQueryManager.executeQuery("node", query);
I am inserting some value into mongodb in this way.
MongoClient mongo = new MongoClient( "localhost" , 27017 );
DB db = mongo.getDB("test");
DBCollection table = db.getCollection("paramDescMapper");
String key = UUID.randomUUID().toString();
String value = "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}";
JSONObject jsonObject = new JSONObject(value);
// create a document to store key and value
BasicDBObject document = new BasicDBObject();
document.put("apiKey", key);
document.put("apiParamDesc", jsonObject.toString());
table.insert(document);
It is inserting data in this way.
{ "_id" : { "$oid" : "534251125f1ab7ec747298cd"} , "apiKey" : "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6" , "apiParamDesc" : "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}"}
Now i want to get apiParamDesc value using apiKey. Like how we get data in mysql.
Select apiParamDesc where apiKey =
'1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6';
I googled a lot but could not found anything. This is how i am trying to get this apiParamDesc
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6");
DBCursor cursor = table.find(whereQuery);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
But this is giving me entire row. I want only apiParamDesc in a String.
Please help me.
Thanks
You can easily do it with aggregation framework. Below is the example which can resolve your issue:
// create our pipeline operations, first with the $match
DBObject match = new BasicDBObject("$match", new BasicDBObject("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"));
// build the $projection operation
DBObject fields = new BasicDBObject("apiParamDesc", 1);
fields.put("_id", 0);
DBObject project = new BasicDBObject("$project", fields );
// run aggregation
AggregationOutput output = collection.aggregate( match, project);
You can also make use of only db.coll.find(< criteria >, < projection >);
BasicDBObject query = new BasicDBObject(new BasicDBObject("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"), new BasicDBObject("apiParamDesc", 1).append("_id", 0));
//Which is equivalent to a follwoing query
//'db.coll.find({"apiKey": "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"}, {"apiParamDesc": 1,"_id": 0});'
cursor = coll.find(query);
One more thing to update you on "I want only apiParamDesc in a String.", is if you are storing string like
"apiParamDesc" : "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}
You cannot query on those sub level fields like param0, param1 ...
You data should look like :
{
"_id":{
"$oid":"534251125f1ab7ec747298cd"
},
"apiKey":"1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6",
"apiParamDesc":{
"param0":"Car Make",
"param1":"Car Model",
"param2":"Car Variant",
"param3":"Car Year",
"param4":"Car Number"
}
}
I want only apiParamDesc in a String.
You cannot however, you can get a document (object) returned with only the apiParamDesc as its single field (my Java is rusty):
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6");
BasicDBObject fields = new BasicDBObject();
fields.put("apiParamDesc", 1);
fields.put("_id", 0);
DBCursor cursor = table.find(whereQuery, fields);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
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