I want to perform a query on a field that is greater than or equal to, AND less than or equal to(I'm using java btw). In other words. >= and <=. As I understand, mongoDB has $gte and $lte operators, but I can't find the proper syntax to use it. The field i'm accessing is a top-level field.
I have managed to get this to work:
FindIterable<Document> iterable = db.getCollection("1dag").find(new Document("timestamp", new Document("$gt", 1412204098)));
as well ass...
FindIterable<Document> iterable = db.getCollection("1dag").find(new Document("timestamp", new Document("$lt", 1412204098)));
But how do you combine these with each other?
Currently I'm playing around with a statement like this, but it does not work:
FindIterable<Document> iterable5 = db.getCollection("1dag").find(new Document( "timestamp", new Document("$gte", 1412204098).append("timestamp", new Document("$lte",1412204099))));
Any help?
Basically you require a range query like this:
db.getCollection("1dag").find({
"timestamp": {
"$gte": 1412204098,
"$lte": 1412204099
}
})
Since you need multiple query conditions for this range query, you can can specify a logical conjunction (AND) by appending conditions to the query document using the append() method:
FindIterable<Document> iterable = db.getCollection("1dag").find(
new Document("timestamp", new Document("$gte", 1412204098).append("$lte", 1412204099)));
The constructor new Document(key, value) only gets you a document with one key-value pair. But in this case you need to create a document with more than one. To do this, create an empty document, and then add pairs to it with .append(key, value).
Document timespan = new Document();
timespan.append("$gt", 1412204098);
timespan.append("$lt", 1412204998);
// timespan in JSON:
// { $gt: 1412204098, $lt: 1412204998}
Document condition = new Document("timestamp", timespan);
// condition in JSON:
// { timestamp: { $gt: 1412204098, $lt: 1412204998} }
FindIterable<Document> iterable = db.getCollection("1dag").find(condition);
Or if you really want to do it with a one-liner without temporary variables:
FindIterable<Document> iterable = db.getCollection("1dag").find(
new Document()
.append("timestamp", new Document()
.append("$gt",1412204098)
.append("$lt",1412204998)
)
);
Related
I'm trying to find all the documents with first name starting with Ram or Shyam.
I tried the following which actually worked in mongoDb
db.collection.find({
$or: [
{
name: {
$regex: "^Ram"
}
},
{
"name": {
"$regex": "^Shyam"
}
}
]
})
I got around count of 4k documents with this find.
Now when I tried to convert this mongo shell query into java.
Things do work but only name starting with Shyam get filtered. As a result the count also decreases to 2k.
Can someone please look at the below code and tell me why is it happening?
Why things are working in mongodb and not in java.
Java Equivalent Code --
MongoDatabase database = mongoClient.getDatabase("Friends");
MongoCollection<Document> collection = database.getCollection("Friend");
BasicDBObject filter = new BasicDBObject("$or", Arrays.asList
(new BasicDBObject("name", new BasicDBObject("$regex", "^Ram")).append("name", new
BasicDBObject("$regex", "^Shyam"))));
collection.find(filter).forEach((Consumer<Document>) doc -> {
// some java function
}
I figured out. There is just one some thing as $or operator always take array
In my java code I have converted it into array but just forgot that there is no need to append .
The solution will be --
BasicDBObject filter = new BasicDBObject("$or", Arrays.asList
(new BasicDBObject("name", new BasicDBObject("$regex", "^Ram")),new BasicDbObject("name", new
BasicDBObject("$regex", "^Shyam"))));
collection.find(filter).forEach((Consumer<Document>) doc -> {
// some java function
}
As per your mongo query, you need to match against name field but not on id field. That's the mistake
BasicDBObject filter = new BasicDBObject("$or", Arrays.asList
(new BasicDBObject("name", new BasicDBObject("$regex", "^Ram"))
.append("id", new //Here is the mistake
BasicDBObject("$regex", "^Shyam"))));
It should be
BasicDBObject filter = new BasicDBObject("$or", Arrays.asList
(new BasicDBObject("name", new BasicDBObject("$regex", "^Ram"))
.append("name", new BasicDBObject("$regex", "^Shyam"))));
I am bit new to mongodb and also in java. I want to query the key breaktime and find the sum of the value.
db.users90.find().pretty()
{
"_id" : ObjectId("5ad5f2e2f58a542f7989e8fc"),
"date" : "2018-04-17",
"break" : [
{
"out" : "18:00",
"in" : "18:40",
"breaktime" : "0:40"
},
{
"out" : "19:00",
"in" : "19:30",
"breaktime" : "0:30"
}
]
}
I need a help in java, to add those 2 breaktime keys(some cases it may be n number of documents in break)
0:40+0:30 = 0:70 minutes
Thanks,
Mohan
Although the query you need is simple, having your "breaktime" values stored as String, makes everything difficult and complex for no reason.
So, assuming you have stored these values as numbers e.g. double, you could easily execute your query in Java like this;
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
new Document("$match", new Document("date","yourDate")), // match a document with a specific date
new Document("$unwind", "$break"), // decompose the 'break' array
new Document("$group", new Document("_id", null).
append("totalBreakTime", new Document("$sum","$break.breaktime"))
)));
if (aggregationQuery.iterator().hasNext()){
double totalBreakTime = ((Document)aggregationQuery.iterator().next()).get("break",Document.class).getDouble("breakTime");
}
I'm trying to load the matched documents into a temporary collection using aggregation query. Actually, I'm able to load all the matched documents into the temporary collection of MongoDB but my java program is throwing Null pointer exception at the for loop.
I'm totally stuck over here. May I know the reason for Null Pointer exception in this scenario . And can anyone please suggest me regarding the same ...
Document query = {"$or":[{"roll":1,"joiningDate":{"$gte":ISODate("2017-04-11T00:00:00Z")}},{"roll":2,"joiningDate":{"$gte": ISODate("2017-03-17T00:00:00Z")}}]};
Document match = new Document("$match",new Document("$or",query));
Document out =new Document("$out","TempCol");
System.out.println("Before Aggregation");
AggregateIterable<Document> resultAgg = collection.aggregate(Arrays.asList(match,out));
System.out.println("After aggregation");
for (Document doc : resultAgg){
System.out.println("The result of aggregation match:-");
}
System.out.println("Completed");
I generally prefer to keep the pipeline structured in one variable.
But the general idea here is use Document where you see {} and Arrays.asList where you see []:
List<Document> pipeline = Arrays.<Document>asList(
new Document("$match",
new Document("$or", Arrays.<Document>asList(
new Document("roll", 1)
.append("joiningDate", new Document(
"$gte", new DateTime(2017,04,11,0,0,0, DateTimeZone.UTC).toDate()
)),
new Document("controlId", 2)
.append("joiningDate", new Document(
"$gte", new DateTime(2017,03,17,0,0,0, DateTimeZone.UTC).toDate()
))
))
),
new Document("$out","TempCol")
);
AggregateIterable<Document> resultAgg = controlIssueCollection.aggregate(pipeline);
Also make sure when constructing a Date object with whatever your favorite construction method here is ( for me org.joda.time.DateTime ) that you are working with time in UTC, unless you really mean otherwise. And if you are comparing with values stored in MongoDB as shown in the shell, then you mean UTC.
Using Java. I have two .find() queries that I want to combine and get a Document containing the results of both queries. I have managed to create them individually like this. Notice that the queries are on two different top-level fields. The last statement below is a query on the same field with two conditions.
FindIterable<Document> iterable = db.getCollection("1dag").find(new Document("id", "10"));
and
FindIterable<Document> iterable2 = db.getCollection("1dag").find(
new Document().append("timestamp", new Document()
.append("$gte",startTime)
.append("$lte",endTime)));
I can't find any documentation on this.
Is this where I should use the "$and" or "$where" statements?
EDIT is this the way to do it?
FindIterable<Document> iterable7 = db.getCollection("1dag").find(
new Document()
.append("timestamp", new Document()
.append("$gte", startTime)
.append("$lte", endTime))
.append("id", new Document()
.append("$eq", 10)));
Your query will work perfectly.
The query db.inventory.find({id:{$eq:10}})
is equivalent to db.inventory.find({id: 10})
So simplifying your query:
FindIterable<Document> iterable7 = db.getCollection("1dag").find(
new Document().append("timestamp", new Document()
.append("$gte", startTime)
.append("$lte", endTime))
.append("id",10));
To create the equivalent Java query for the following mongo shell query
db.getCollection("1dag").find({
"id": "10",
"timestamp": {
"$gte": 1412204098,
"$lte": 1412204099
}
})
you should specify a logical conjunction (AND) for multiple query conditions by appending conditions to the query document:
FindIterable<Document> iterable = db.getCollection("1dag").find(
new Document("id", "10")
.append("timestamp",
new Document("$gte", 1412204098)
.append("$lte", 1412204099)
)
);
Can anyone explain me why in Java when i do an aggregation pipeline with "$out" don't write the result in the new collection when i write only this:
Document match = new Document("$match", new Document("top_speed",new Document("$gte",350)));
Document out=new Document("$out", "new_collection");
coll.aggregate(Arrays.asList(
match,out
)
);
When I save the aggregation result and I iterate on it, the new collection is created and the result of the match is inside (Java has an error obviously in this case):
AggregateIterable<Document> resultAgg=
coll.aggregate(Arrays.asList(
match,out
)
);
for (Document doc : resultAgg){
System.out.println("The result of aggregation match:-"+ doc.toJson());
}
I can't understand why.
You can call toCollection() method instead of iterating.
Document match = new Document("$match", new Document("top_speed", new Document("$gte", 350)));
Document out = new Document("$out", "new_collection");
coll.aggregate(Arrays.asList(match, out)).toCollection();