通过Morphia(MongoDB)推送到嵌入式子文档中的数组

时间:2017-04-12 18:12:54

标签: java mongodb morphia

TL; DR我希望将对象列表推送到mongodb中的数组;这个数组嵌套在一个嵌入式子文档中,我不知道如何到达这个数组,而没有先从数据库中检索整个主文档。

首先,我的主要实体:

@Entity("trackers")
public class Tracker {

    @Id
    private ObjectId id;
    private String ican;
    @Embedded
    private List<Day> days;

    //getters, setters & constructors
}

Day对象如下所示:

@Embedded
public class Day {

    private LocalDate date;
    @Embedded
    private List<GeoStamp> geoStamps;

    //getters, setters & constructors
}

最后,geostamp对象看起来像这样:

@Embedded
public class GeoStamp {

    private Date dateTime;
    private double latitude;
    private double longitude;

    //getters, setters & constructors
}

现在,在我的数据库中,这最终看起来像这样:

{
    "_id" : ObjectId("58ee636b44e7ed48200ee8d4"),
    "className" : "com.model.Tracker",
    "ican" : "NL 12346",
    "days" : [
        {
            "date" : ISODate("2017-04-11T22:00:00Z"),
            "geoStamps" : [
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                },
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                },
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                }
            ]
        },
        {
            "date" : ISODate("2017-01-01T23:00:00Z"),
            "geoStamps" : [
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                },
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                },
                {
                    "dateTime" : ISODate("2017-04-12T17:27:07.249Z"),
                    "latitude" : 23.2222,
                    "longitude" : 44.333
                }
            ]
        }
    ]
}

现在我想做的是将GeoStamp列表推送到Mongo中的GeoStamp数组,在那里我首先过滤Tracker的ObjectId或它的ican。然后在文档中发现我需要按天过滤,因此我不会将GeoStamp列表添加到分布在多个日期的多个GeoStamp阵列。

我认为能够通过以下方式实现:

我的查询(是的,我知道retrieveFields已被弃用,我宁愿不使用它,但这是我最接近工作的解决方案):

final Query<Tracker> trackerQuery = datastore.find(Tracker.class)
                .filter("_id", id)
                .filter("days.date", LocalDate.now())
                .retrievedFields(true, "days.$");

我的updateOperations(newGeoStamps是要添加的GeoStamp对象列表):

final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class).push("days.geoStamps", newGeoStamps);

最后,updateResults:

final UpdateResults trackerUpdateResults = datastore.update(trackerQuery, trackerUpdate);

这会抛出WriteConcernException,并显示以下错误:

  

写入失败,错误代码为16837,错误消息&#39;无法使用该部分(days.geoStamps天数)遍历该元素({days:[{date:new Date(1491948000000),geoStamps:[{dateTime :new Date(1492019739661),纬度:23.2222,经度:44.333},{dateTime:new Date(1492019739661),纬度:23.2222,经度:44.333},{dateTime:new Date(1492019739661),纬度:23.2222,经度:44.333 }]},{date:new Date(1483311600000),geoStamps:[{dateTime:new Date(1492019739661),纬度:23.2222,经度:44.333},{dateTime:new Date(1492019739661),纬度:23.2222,经度:44.333 },{dateTime:new Date(1492019739661),纬度:23.2222,经度:44.333}]}]})&#39;

您在错误中看到的纬度和经度是我试图插入的。

关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:0)

原来我实际上并没有推动阵列,这个:

final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class).push("days.geoStamps", newGeoStamps);

应该是:

final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class)
                .push("days.$.geoStamps", newGeoStamps);

希望这可能会对将来有所帮助!