Advanced logical operations in MongoDB with Java Driver - java

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);

Related

mongodb java driver with $match and $gruop

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

Mongo Query with $in array in Java

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);

How to $and two documents in mongodb and Java?

I am using mongodb with Java 3.0 driver. I have a scenario where I have to perform logical and i.e, $and on my queries. For example, I have two documents already created and I am trying to do something like this:
iterable = mongoDatabase.getCollection("restaurants").find(
new Document("$and", asList(abc,
updatedDocumentTypeOne)));
where abc is one document and updatedDocumentTypeOne is another document. I found this in mongodb manual but I am getting error as first create asList Method.
Or how to replicate the following in Java:
db.inventory.find( {
$and : [
{ $or : [ { price : 0.99 }, { price : 1.99 } ] },
{ $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
]
} )`
You can also try the code below that adds a filter for query replication in Java:
// Where db is the object reference of "inventory" collection's database
MongoCollection<Document> inventory = db.getCollection("inventory");
//List for result return
List<Document> result = new ArrayList<Document>();
//Query replication in Java and return result into the list
inventory.find(Filters.and(
Filters.or(Filters.eq("price", 0.99),Filters.eq("price", "1.99")),
Filters.or(Filters.eq("sale", true),Filters.lt("qty", 20))
)).into(result);
Change from asList() to Arrays.asList()
Instead of writing Arrays.asList(), you have specified as asList(). So compiler is searching for the method asList(), which is NOT available.
Check the below code :
iterable = mongoDatabase.getCollection("restaurants").find(
new Document("$and", Arrays.asList(abc,
updatedDocumentTypeOne)));
For your above query, You can code as below :
/* First OR condition */
Document price1 = new BasicDBObject("price",0.99);
Document price2 = new BasicDBObject("price",1.99);
BasicDBList or_first = new BasicDBList();
or_first.add(price1);
or_first.add(price2);
DBObject query = new BasicDBObject("$or", or_first);
/* Second OR condition */
boolean val = true;
Document sale = new BasicDBObject("sale",val);
Document qty = new BasicDBObject("qty", new BasicDocument("$lt",20));
BasicDBList or_second = new BasicDBList();
or_second.add(sale);
or_second.add(qty);
DBObject query = new BasicDBObject("$or", or_second);
/* AND condition logic */
BasicDBList and_op = new BasicDBList();
and_op.add(or_first);
and_op.add(or_second);
iterable = mongoDatabase.getCollection("restaurants").find( new Document("$and", and_op ));

How to write group by with add operation in MongoDB Java driver

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]}}}}

Iterate aggregate output in java

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

Categories