I have a mongo query to be executed :
query = { "dateField" : { "$gte" : ISODate('2011-11-10T07:45:32.962Z') } }
When I do a db.Collection.find(query) on the mongo shell, I am able to retrieve the results.
How could I query this using Java ? I tried constructing a String based on the Date parameter.
But in the process of building the String, it eventually gets passed as "ISODate('2011-11-10T07:45:32.962Z')" instead of ISODate('2011-11-10T07:45:32.962Z') (without the surrounding quotes).
What would be the best way to construct this query using the Java API ?
Thanks !
Use a regular Java Date--also I recommend the QueryBuilder:
Date d = new Date(); // or make a date out of a string...
DBObject query = QueryBuilder.start().put("dateField").greaterThanEquals(d).get();
I have search lot and spend more than hour in finding how to get data when having ISODate in mongo model.
As the default constructor for date is deprecated so it was not working in my case.
BasicDBObject searchQuery = new BasicDBObject("_id" , 1);
try {
searchQuery.append("timestamp",BasicDBObjectBuilder.start( "$gte",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS\'Z\'").parse("2015-12-07T10:38:17.498Z")).get());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Related
My project is using Oracle database, and everything works just fine. For the purpose of testing I set up an H2 db. The following query now throws an error:
"SELECT * FROM ERESIS.ECH_HISFAB f WHERE f.FG_ETAT = 'A' AND TO_DATE(DT_INS) > '30-AUG-18' ORDER BY f.CD_MAT"
error:
Cannot parse "TIMESTAMP" constant "30-AUG-18"; SQL statement:
I can fix the error by setting up the string like TO_DATE('30-AUG-2018'), but changing the query kind of defeats the purpose since I already am sure the query works (but I need it to test the service). Is there any way to bypass this error without changing the query?
parsedatetime() should be able to convert string to TIMESTAMP, please try using -
"SELECT * FROM ERESIS.ECH_HISFAB f WHERE f.FG_ETAT = 'A' AND TO_DATE(DT_INS) > parsedatetime('30-AUG-2018', 'dd-MMM-yyyy') ORDER BY f.CD_MAT"
I had a similar issue with H2 (1.4.200), it has just one format for TO_DATE(input) method "DD MON YYYY".
After a debug I found that H2 uses an enum for date format when it's not provided as second parameter: org.h2.expression.function.ToDateParser.ConfigParam
TO_DATE("DD MON YYYY")
I did a solution to override it using reflection so that the sql code does not change.
In my unit test I created a utility method used to instantiate the workaround on #BeforeClass
private static boolean h2WorkaroundApplied = false; //utility to apply workaround just one time
protected static synchronized void applyH2ToOracleCompatibilityWorkaround() {
if (!h2WorkaroundApplied) {
fixH2ToDateFormat(); //apply to_date workaround
h2WorkaroundApplied = true; //disable future changes of same workaround
}
}
private static void fixH2ToDateFormat() {
try {
Class<?> classConfigParam = Arrays.stream(ToDateParser.class.getDeclaredClasses())
.filter(c -> "ConfigParam".equals(c.getSimpleName()))
.findFirst()
.orElseThrow(); //get the enum inner class
Object toDateEnumConstant = Arrays.stream(classConfigParam.getEnumConstants())
.filter(e -> "TO_DATE".equals(((Enum) e).name()))
.findFirst()
.orElseThrow(); //get the enum constant TO_DATE
Field defaultFormatStr = classConfigParam.getDeclaredField("defaultFormatStr"); //get the enum private field defaultFormatStr
defaultFormatStr.setAccessible(true);
defaultFormatStr.set(toDateEnumConstant, "YYYY-MM-DD"); //change with my date format used by production oracle DB.
} catch (Exception e) {
throw new UnsupportedOperationException(
"The current H2 version doesn't support this workaround. Tested with version 1.4.200", e);
}
}
I have been looking and trying solutions provided on the web (and SO) for the last hour on how to use the Date type in Java but I can't seem to get it working. I am using NetBeans 11.2 and I am not used to Java and it is giving me a hard time (no pun intended). It seems that LocalDateTime, Date and Time are deprecated and that I should be using java.time.
To be honest, I don't know what to do anymore. I am trying to build a query with inputs value to save in mySQL database.
The source of the Date is from <input type="date">
SignIn.java (servlet) :
String birthDate = request.getParameter("data_birthdate");
UserDto userDto = null;
UserDao userDao = new UserDao();
try
{
// Tried this
userDto = userDao.CreateUser(LocalDateTime.parse(birthDate));
// Tried that
userDto = userDao.CreateUser(Date.parse(birthDate));
// Tried this
userDto = userDao.CreateUser(Time.parse(birthDate));
}
userDao.java (Dao) :
public void CreateUser(Date dateBirth) throws SQLException {
try {
connect = db.getConnect();
ps = connect.prepareStatement(SQL_CreateUser);
ps.setDate(1, dateBirth);
ps.executeUpdate();
}
}
You may use LocalDateTime along with PreparedStatement#setTimestamp(). Here is roughly how you would do that:
String birthDate = request.getParameter("data_birthdate");
// assuming your text birthdates look like 1980-12-30 00:30:05
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dt = LocalDateTime.parse(birthDate, formatter);
try {
connect = db.getConnect();
ps = connect.prepareStatement(SQL_CreateUser);
ps.setTimestamp(3, Timestamp.valueOf(dt));
}
catch (Exception e) {
// handle exception
}
Note carefully the format mask being used in the call to DateTimeFormatter#ofPattern. You need to replace that with whatever mask actually fits your string dates.
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).
I want to ask how can I make queries for this. I want to check the name from edit text and if the name exsist, as a part of record, in db i want to fill all edit texts with data from this object. Also I've got very strange error. Please help or give me an advice how to start with it. Im beginner. Thanks for all answers and clues.
Here is my code:
if(et_nazwa!=null){
long value = 0;
try {
PreparedQuery<Klient> query = klientDao.queryBuilder()
.where().eq("Kli_nazwa",et_nazwa.getText().toString()).prepare();
value = klientDao.countOf(query);
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(value!=0){
PreparedQuery<Klient> q_adres = klientDao.queryBuilder().selectColumns("Kli_adres").where().eq("Kli_nazwa",et_nazwa.getText().toString()).prepare();
PreparedQuery<Klient> q_nip = klientDao.queryBuilder().selectColumns("Kli_nip").where().eq("Kli_nazwa",et_nazwa.getText().toString()).prepare();
et_adres.setText(q_adres.toString());
et_nip.setText(q_nip.toString());
}
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And I've got this strange error like:
java.lang.IllegalArgumentException: Prepared query is not of type SELECT_LONG, did you call QueryBuilder.setCountOf(true)?
java.lang.IllegalArgumentException: Prepared query is not of type SELECT_LONG, did you call QueryBuilder.setCountOf(true)?
So the exception is trying to tell you what went wrong. When you build a query, ORMLite does not know what the query is going to be used for. Because you can select various columns and the like or use aggregate functions (like MAX(...)) it records an internal query-type and then checks it when the query is executed.
If you want to use Dao.countOf(...) then you need to add setCountOf(true) on your QueryBuilder object. The docs for Dao.countOf(...) should be made more explicit of this fact.
PreparedQuery<Klient> query = klientDao.queryBuilder().setCountOf(true)
.where().eq("Kli_nazwa",et_nazwa.getText().toString()).prepare();
If you use queryBuilder.countOf() or where.countOf() then it will set the count-of flag internally. You can get the count of the query without this problem by doing:
value = klientDao.queryBuilder()
.where().eq("Kli_nazwa",et_nazwa.getText().toString()).countOf();
Btw, this is a strange pattern:
et_adres.setText(((PreparedQuery)q_adres).toString());
Maybe you wanted to do the following?
String queryString = klientDao.queryBuilder()...prepareStatementString();
I need to insert a list of objects with a predefined _id (Long) into a collection.
insert(object) method for a single object from AdvancedDatastore works great. The trouble begins when i try to use the insert() method which accepts an Iterable. Here is a sample piece of code:
try {
advancedDatastore.insert("collection_name", feeds, WriteConcern.ERRORS_IGNORED);
} catch (Exception e) {
e.printStackTrace();
}
I guess that this code is supposed to ignore errors (an object with a duplicate id already exists in the collection) and just continue with the next item, but it does not. And no exception is raised.
Thanks!
Update:
This code inserts all the elements, but "1" is not printed out.
try {
System.err.println(0);
advancedDatastore.insert("collection_name", feeds, WriteConcern.ERRORS_IGNORED.continueOnErrorForInsert(true));
System.err.println(1);
} catch (Exception e) {
e.printStackTrace();
}
Update2:
Sorry, the code completes properly and "1" is printed out, but it takes tremendously more time than single inserts. In my case 35_000 inserts 1 by one - 3 seconds, in batch - 100+ seconds
Update3:
So far the best way to deal with the issue for me is to use native java driver for mongodb.
1st I convert my object list to DBObject list:
final List<DBObject> dbObjects = new ArrayList<DBObject>();
for (MyObject object: objectList) {
dbObjects.add(morphia.toDBObject(object));
}
Then I insert through mongo DB instance:
db.getCollection("collection_name").insert(dbObjects, WriteConcern.UNACKNOWLEDGED.continueOnErrorForInsert(true));
Performace for inserting 150_000 objects:
Native DB insert: 2-3 seconds
via Morphia's insert(object): 15+ seconds
via Morphia's insert(Iterable): 400+ seconds
A better way would be appreciated.
It works to me in this way
final List<DBObject> dbObjects = new ArrayList<DBObject>();
try {
TypedQuery<RegistroCivil> consulta = em.createQuery("select p from RegistroCivil p", RegistroCivil.class);
List<RegistroCivil> lista = consulta.getResultList();
for (RegistroCivil object : lista) {
dbObjects.add(morphia.toDBObject(object));
}
long start = System.currentTimeMillis();
ds.getCollection(RegistroCivil.class).insert(dbObjects);
//ds.save(lista);
long end = System.currentTimeMillis();
tmongo = end - start;