Inserting MongoDB long values with Java - java

I'm attempting to insert a date, as a long value, into MongoDB in Java. When I attempt to insert one, it appears as NumberLong("12345"), which appears to be a string within NumberLong(). Unless this is a misunderstanding of mine.
This is my line of code--where parserSDF is a Java Date object:
BasicDBObject dbDate = new BasicDBObject("dateCreated",parserSDF.getTime());
This is how the field appears by default:
... "dateCreated" : NumberLong(0) ...
But this is how it changes when attempting to write a long:
"dateCreated" : NumberLong("1426632572797")

Related

Unable to find a document in Mongodb where exact date match in java

Statement: I am trying to get the documents from MongoDB collection (Emp) using java.
Condition: Where it matches with the DOB(Date of birth) of a person.
Problem: However, it never returns a record.
But it works perfectly for other fields such as EmpID or EmpName etc. The document of my collection looks like this,
{
"_id" : ObjectId("5d4d9059f0b31921a4916a0c"),
"EmpID" : "1001",
"EmpName" : "John",
"Sal" : 30000.0,
"DOB" : ISODate("1989-06-09T18:30:00.000+0000"),
"Age" : 31.0
}
Please find the following java code that I have tried,
BasicDBObject dbo = new BasicDBObject();
dbo.append("DOB", new BasicDBObject("$eq","1989-06-10T00:00:00.000"));
FindIterable<Document> doc = coll.find(dbo);
for (Document dox : doc)
{
System.out.println(dox.toJson());
}
Please help
For ISODate it's needed to pass the Date object in BasicDBObject, not String, also timezone must be provided:
dbo.append("DOB", new BasicDBObject("$eq",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX").parse("1989-06-10T00:00:00.000+0000")));
For Date Of Birth better to use $gte and $lt comparition operators together in order to take full range of single day, like that:
Date dayStart = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX").parse("1989-06-10T00:00:00.000+0000");
Date dayEnd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX").parse("1989-06-11T00:00:00.000+0000");
BasicDBObject query = new BasicDBObject("Date", new BasicDBObject("$gt", dayStart).append("$lte", dayEnd));

Remove multiple array Entries on Mongo using MongoOperations

I already can execute the desired query on mongoshell, but i need to make the same query using Java and MongoOperations.
I have checked this question, which is very similar, but it only has one condition, as mine has two and uses the $gte and $lt operators. Here's the working mongo Query:
db.getCollection('example').update({"idVar": "desiredValued"}, { $pull: { "listaHoras": { $gte: ISODate("2016-11-06T05:50:00.000Z"), $lt: ISODate("2016-11-06T06:30:00.000Z")}}})
Sample doc:
"_id" : ObjectId("58221b4610a3c71f1894ce75"),
"idVar" : "56b11259272f5515b05d70bc",
"date" : ISODate("2016-11-06T03:00:00.000Z"),
"listaHoras" : [
ISODate("2016-11-06T05:40:00.000Z"),
ISODate("2016-11-06T06:30:00.000Z"),
ISODate("2016-11-06T06:40:00.000Z")
]
Where i'll have the ISODATE as a Date variable in Java, and the desiredValue as a String variable.
So far, i have i did the following, using the previously mentioned question as example:
BasicDBObject match = new BasicDBObject("idVar", desiredValue); // to match your document
BasicDBObject update = new BasicDBObject("listaHoras", new BasicDBObject("itemID", "1"));
coll.update(match, new BasicDBObject("$pull", update));
But, as you can see, this is NOT equivalent to the desired query. Since the match for the $pull is matching "itemID"with "1". I do not know, nor was i able to find how to properly use the $gte and $lt on the same query. Neither on how to use just one or both of them. I know it CAN be done as seen on the MongoOperatioons API which says:
"update - the update document that contains the updated object or $ operators to manipulate the existing object."
Anyone knows how it can be done? And if the Date type in Java matches the ISODATE on the Mongo?
I managed to find a solution. It is similar to what Veeram posted as a answer but it's slightly different. I simply removed his updateCriteria and used a BasicDBObject in it's place.
Here's how the full code looks:
Query findQuery = new Query();
Criteria findCriteria = Criteria.where("idVar").is(idVar);
findQuery.addCriteria(findCriteria);
Update update = new Update().pull("listaHoras", new BasicDBObject( "$gte", start).append("$lte", end));
mongoOps.updateMulti(findQuery, update, "CollectionName");
Where start and end are Date variables recieved by the method. Also important to note that Mongo uses the UTC as default timezone, so we must properly format the time in order for it to remove the desired values.
You can try something like below. This will remove the two items from the listaHoras array.
Query findQuery = new Query();
Criteria findCriteria =
Criteria.where("idVar").is("56b11259272f5515b05d70bc");
findQuery.addCriteria(findCriteria);
LocalDate startDt = LocalDate.of(2016, 11, 6);
LocalTime startTm = LocalTime.of(5, 40, 0);
LocalDate endDt = LocalDate.of(2016, 11, 6);
LocalTime endTm = LocalTime.of(6, 35, 0);
Date start = Date.from(LocalDateTime.of(startDt, startTm).toInstant(ZoneOffset.UTC));
Date end = Date.from(LocalDateTime.of(endDt, endTm).toInstant(ZoneOffset.UTC));
Query updateQuery = new Query();
Criteria updateCriteria =
Criteria.where(null).gte(start).lt(end);
updateQuery.addCriteria(updateCriteria);
mongoOperations.updateMulti(findQuery, update, "example");

Query for binary data - MongoDB

I'm using Java Driver for MongoDB (2.14) in my application.
I have these documents:
{ "_id" : ObjectId("56fb9798e2445ade35effa89"), "b" : BinData(3,"abcdefgh") }
{ "_id" : ObjectId("56fba265e2445ade35effa8c"), "b" : 1 }
I have to retrieve all documents where "b" is a binary data using Java.
To reach my target I use the following query:
DBObject query = new BasicDBObject(b, new BasicDBObject("$type",5));
DBObject projKeys = new BasicDBObject();
projKeys.put("_id", 0);
projKeys.put(b, 1);
DBCursor cursor = coll.find(query,projKeys);
But when I start to iterate over cursor I get an exception:
java.lang.IllegalArgumentException: bad data size subtype 3 len: 6 != 16
When I try to make the same query using mongo shell, that is:
db.coll.find({b:{"$type":5}}, {_id:0,b:1})
I don't have errors.
Binary subtype 3 is reserved for UUID, which has a "strict" 16 byte length ( 32 string elements in hex notation ). Hence the error you are getting in your Java code.
The MongoDB shell does not have this "strict" typing, and as such both allows the creation and reading of the data. Nor is MongoDB itself "strictly typed", so as far as the engine is concerned it's just BSON Type 5, and does not look at it further.
If you inserted documents either use the correct data for the subtype:
{ "b": BinData(3,"ASNFZ4mrze/+3LqYdlQyEA==") }
Or a corrected subtype suiting the data, such a 0:
{ "b": BinDta(0,"abcdefgh") }
Then the Java driver has no problem when marshalling into it's Binary type.
So you get the error because your "data" is "invalid". Correct the data and there is no problem.

Cannot find sub-field

I have this data on my mongodb database:
{
"_id" : BinData(3, "bU0bX4VEAMnW7AJ28wXcoA=="),
"online" : false,
"money" : 0,
"rank" : "USER",
"ban" : {
"end" : NumberLong("3027259780628"),
"reason" : "hello"
}
}
and I use this code to access to the ban.end sub-field saved in it:
final Document doc = collcetion.find(new Document("_id", myId)).
projection(Projections.include("ban.end"));
System.out.println(doc); // here is all ok.
// It print out the _id with the
// ban and the end values.
final long a = doc.getLong("ban.end"); // nullptr exception because
// I tryied to do this:
long a = (Long) null;
Is there any way to fix the null pointer reported above? I think I failed something with mongodb, I'm not sure in using ban.end as field name.
I already tried to get, for example, the money value and it works.
getLong returns a Long, not a long. See http://api.mongodb.org/java/current/org/bson/Document.html#getLong-java.lang.Object-.
In other words, you're getting the nullpointer because you're implicitly unboxing it. Just use
final long a = doc.getLong("ban.end");
instead, the handle the null case separately.
I'm not sure in using "ban.end" as field name.
Sadly, you are. You need to get the ban objcect first, before you could access its end attribute.
The logic remains the same for whatever versions.
code in 3.0.4 version of the java driver,
DBCursor docs = collection.find(new BasicDBObject("_id", myId),
new BasicDBObject("ban.end", 1));
while (docs.hasNext())
{
BasicDBObject banObj = (BasicDBObject) docs.next().get("ban");
long end = banObj.getLong("end");
System.out.println(end);
}

MongoDB Date Search In Java returning zero results

I have a list of files in a GridFS that I am attempting to query by date. The sample document looks like the following:
{
"_id" : ObjectId("52e431d3e84f6fa18c53c808"),
"chunkSize" : NumberLong(262144),
"length" : NumberLong(13021),
"md5" : "0eb01f0d266f4bf4764d4ffc7e70a7ed",
"filename" : "120_1390686674383",
"contentType" : null,
"uploadDate" : ISODate("2014-01-25T21:51:15.049Z"),
"aliases" : null
}
I am attempting to get the "most recent" according to timestamp by doing the following:
DateTime dt = new DateTime(queryObj.getTime()); //org.joda.DateTime
BasicDBObject sort = new BasicDBObject();
sort.put("uploadDate", -1);
BasicDBObject query = new BasicDBObject();
query.put("uploadDate", new BasicDBObject("$gte", dt));
DBCursor cursor = fileStore.getFileList(query, sort);
If I simply sort the fileStore I get numerous records back and I can enumerate via the cursor. However, whenever I try to use $gte or $lte I get zero results.
Is there a missing step?
You're passing in a joda DateTime reference which the driver doesn't know how to do. If you check the logs, you'll probably find that it essentially calls a toString() on that and passes that in. Since a string is not a Date, the comparison fails. Try passing in just a java.util.Date (you can get one from the DateTime, iirc).

Categories