来自BasicDBObject的MongoDB getDate

时间:2013-12-23 18:28:50

标签: java mongodb

我从MongoDB游标返回数据BasicDBObject,其toString()返回以下数据:

{ 
    "_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 
}

我尝试获取"start"字段(Date)值但抛出java.lang.NullPointerException

我的Java代码:

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

问题:如何从文档中提取"start""end"字段值?

Java驱动程序:2.4.x

4 个答案:

答案 0 :(得分:1)

您可以使用org.joda.time.DateTime,

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

答案 1 :(得分:1)

我写了两个测试来说明行为应该是什么。我无法得到任何东西来抛出NullPointerException,所以我认为它可能在你的代码中的其他地方。你可以发布整个堆栈跟踪吗?或者单步执行调试器?

这些测试表明getDate方法是正确的,如果Date值为null或该字段不存在,它将不会出错:

@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()));
}

这两个测试都没有错误地通过。

如果值为null,JsonObject.append方法可能会抛出错误。您应该在将它们放入JsonObject之前检查这些值,因此您可能需要将代码更改为:

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

答案 2 :(得分:0)

如果您使用类似SpringData的东西,那么它将从数据库加载对象并使用它来填充Java Bean的字段,包括正确地将其解析为Date字段等。

如果您不想这样做,那么DateFormat类允许您指定String的格式,然后将该String解析为新的Date对象。

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

答案 3 :(得分:-1)

data.getDate("start")将返回一个BasicDBObject。在这种情况下,这个BasicDBObject实际上是一个其他BasicDBObjects的数组,所以我们必须这样抛出它。

ArrayList startDate =(ArrayList)data.getDate(“start”);

您可以从arrayList startDate获取日期:

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

试试这个。