Reddy
Reddy

Reputation: 1453

MongoDB getDate from BasicDBObject

I have return data BasicDBObject from MongoDB cursor and its toString() return following data:

{ 
    "_id" : { "$oid" : "52b8775ebf552f39c2ae5cf2"} , 
    "patient" : {
        "$ref" : "patients" , 
        "$id" : "52b848ae65b9f1856f630dd8"} , 
    "doctor" : { 
        "$ref" : "doctors" , 
        "$id" : "5294f0a76297040bf2aa6b53"} , 
    "type" : "opd" , 
    "title" : "Not feeling well" , 
    "start" : { "$date" : "2013-12-24T00:30:00.000Z"} , 
    "end" : { "$date" : "2013-12-24T00:30:00.000Z"} , 
    "reference_doctor_id" :  null 
}

I tried getting the "start" field (Date) value but throwing java.lang.NullPointerException.

My Java code:

final BasicDBObject data = (BasicDBObject) rs.next(),
patient = (BasicDBObject) ((DBRef) data.get("patient")).fetch();
final JsonObject resp = new JsonObject();
System.out.println("Appointments : \n"+data.toString());
resp.putValue("start", data.getDate("start"))
    .putValue("end", data.getDate("end"))
    .putValue("_id", (data.getObjectId("_id")).toString())
    .putValue("type", data.get("type"))
    .putValue("name", patient.get("name"))
    .putValue("patient", (patient.getObjectId("_id")).toString());

Question: How to extract the "start" and "end" field value from the document?

Java driver: 2.4.x

Upvotes: 1

Views: 7415

Answers (5)

Vladi
Vladi

Reputation: 1990

import com.jayway.jsonpath.JsonPath;

JsonPath.parse(data).read("start");

Upvotes: -1

jjmartinez
jjmartinez

Reputation: 807

data.getDate("start") will return a BasicDBObject. In this case, this BasicDBObject is actually an array of other BasicDBObjects, so we must cast it as such.

ArrayList startDate = (ArrayList)data.getDate("start");

And you can get the date from the arrayList startDate:

for(BasicDBObject embedded : startDate){
  Date start= (Date)embedded.get("$date");
  System.out.println("the date is : " + start);
}

Try with this.

Upvotes: -1

Trisha
Trisha

Reputation: 3931

I've written two tests to show what the behaviour should be. I can't get anything to throw the NullPointerException, so I think it might be somewhere else in your code. Can you post the whole stack trace? Or step through a debugger?

These tests show that the getDate method is the correct one, and that it will not error if the Date value is null or the field does not exist:

@Test
public void shouldRetrieveDatesFromADocument() {
    // Given - store a really basic document with start and end dates in the database
    Date startDate = new Date(2468000000L);
    Date endDate = new Date(12468000000L);
    BasicDBObject patient = new BasicDBObject("start", startDate)
                                      .append("end", endDate);
    collection.insert(patient);

    // When - find the value we saved into the database
    DBCursor rs = collection.find();
    BasicDBObject data = (BasicDBObject) rs.next();

    // Then - check the values are correct and no errors are thrown
    assertThat(data.getDate("start"), is(notNullValue()));
    assertThat(data.getDate("start"), is(startDate));
    assertThat(data.getDate("end"), is(notNullValue()));
    assertThat(data.getDate("end"), is(endDate));
}

@Test
public void shouldNotThrowNullPointerIfFieldNotPresent() {
    // Given - put a really basic document with no start and end fields into the database
    BasicDBObject patient = new BasicDBObject("type", "opd");
    collection.insert(patient);

    // When
    DBCursor rs = collection.find();
    BasicDBObject data = (BasicDBObject) rs.next();

    // Then
    assertThat(data.getDate("start"), is(nullValue()));
    assertThat(data.getDate("end"), is(nullValue()));
}

Both these tests pass without error.

It's possible the JsonObject.append method will throw an error if the value is null. You should check the values before you put them into your JsonObject, so you might need to change your code to something like:

final JsonObject resp = new JsonObject();
System.out.println("Appointments : \n"+data.toString());
resp.putValue("_id", (data.getObjectId("_id")).toString())
    .putValue("type", data.get("type"))
    .putValue("name", patient.get("name"))
    .putValue("patient", (patient.getObjectId("_id")).toString());
Date startDate = data.getDate("start");
Date endDate = data.getDate("end");
if (startDate != null) {
    resp.putValue("start", startDate);
}
if (endDate != null) {
    resp.putValue("end", endDate);
}

Upvotes: 1

Tim B
Tim B

Reputation: 41208

If you use something like SpringData then it will load the object from the database and use it to populate the fields of a Java Bean, including parsing it into Date fields correctly, etc.

If you don't want to do that then the DateFormat class allows you to specify the format of a String and then parse that String into a new Date object.

http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#parse%28java.lang.String%29

Upvotes: 0

Laki M
Laki M

Reputation: 46

You can use org.joda.time.DateTime,

new DateTime(data.get("start"))

Upvotes: 2

Related Questions