Transforming MongoDB query to Java with $elemMatch - java

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

Related

Run an aggregation using Java Driver - MongoDB

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.

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")}}}
] );

MongoDB Update Multiple Documents based on ObjectID (_id)

I'm using the Java driver with MongoDB. I have a List of document id's in a collection. I want to update a single field in every document that has an "_id" equal to one of the document id's in my List. In the below example, I tried something like this:
List<ObjectID> list = new ArrayList<ObjectID>();
list.append(new ObjectId("123"));
list.append(new ObjectId("456"));
list.append(new ObjectId("789"));
column.updateMulti(new BasicDBObject("_id", list),new BasicDBObject("$set",new BasicDBObject("field",59)));
My intentions are to update the documents with _id=123, _id=456 and _id=789, setting their "field" attribute to 59.
Am I going about this the right way?
I believe you need to make a couple changes:
BasicDBList list = new BasicDBList();
list.add( new ObjectId("123") );
// Add the rest...
DBObject inStatement = new BasicDBObject( "$in", list );
column.updateMulti( new BasicDBObject( "_id", inStatement ), new BasicDBObject( "$set", new BasicDBObject( "field", 59 ) );
Otherwise, with your current query, you're doing an equality comparison of the _id property against a list of _ids - not actually using the $in operator.

Categories

Resources