简体   繁体   English

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

[英]Pushing to array in embedded subdocument via Morphia (MongoDB)

TL;DR I wish to push a list of objects to an array in mongodb; TL; DR我希望将对象列表推送到mongodb中的数组; this array is nested in an embedded subdocument, and I don't know how to reach this array, without first retrieving the entire main document from the database. 该数组嵌套在嵌入式子文档中,如果不先从数据库中检索整个主文档,我不知道如何到达此数组。

First, my main entity: 首先,我的主要实体:

@Entity("trackers")
public class Tracker {

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

    //getters, setters & constructors
}

A Day object looks like this: Day对象看起来像这样:

@Embedded
public class Day {

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

    //getters, setters & constructors
}

And lastly, a geostamp object looks like this: 最后,一个geostamp对象看起来像这样:

@Embedded
public class GeoStamp {

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

    //getters, setters & constructors
}

Now, in my database this ends up looking like this: 现在,在我的数据库中,结果看起来像这样:

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

Now what I wish to do is push a list of GeoStamps to a GeoStamp array in Mongo, where I first filter on either the ObjectId of a Tracker, or its ican. 现在,我想做的是将一个GeoStamps列表推送到Mongo中的GeoStamp数组,在这里我首先对Tracker的ObjectId或其ican进行过滤。 Then within the document found I need to filter by day, so I don't add the GeoStamp list to multiple GeoStamp arrays spread out over multiple dates. 然后,在找到的文档中,我需要按天过滤,因此,我不会将GeoStamp列表添加到分布在多个日期的多个GeoStamp阵列中。

I thought to be able to do it in the following way: 我认为可以通过以下方式做到这一点:

My query (yes I know retrievedFields is deprecated and I'd rather not use it, but this was my solution that came closest to working): 我的查询(是的,我知道不建议使用retriedFields,而我宁愿不使用它,但这是我最接近工作的解决方案):

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

My updateOperations (newGeoStamps is the list of GeoStamp objects to be added): 我的updateOperations(newGeoStamps是要添加的GeoStamp对象的列表):

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

And lastly, updateResults: 最后,updateResults:

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

This throws a WriteConcernException with the following error: 这将引发带有以下错误的WriteConcernException:

Write failed with error code 16837 and error message 'cannot use the part (days of days.geoStamps) to traverse the element ({days: [ { date: new Date(1491948000000), geoStamps: [ { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 }, { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 }, { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 } ] }, { date: new Date(1483311600000), geoStamps: [ { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 }, { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 }, { dateTime: new Date(1492019739661), latitude: 23.2222, longitude: 44.333 } ] } ]})' 写入失败,错误代码为16837,错误消息为“无法使用部分(days of days.geoStamps)遍历元素({days:[{date:new Date(1491948000000),geoStamps:[{dateTime:new Date(1492019739661) ,纬度:23.2222,经度:44.333},{dateTime:新日期(1492019739661),纬度:23.2222,经度:44.333},{dateTime:新日期(1492019739661),纬度:23.2222,经度:44.333}]},{日期:新日期(1483311600000),geoStamps:[{dateTime:新日期(1492019739661),纬度:23.2222,经度:44.333},{dateTime:新日期(1492019739661),纬度:23.2222,经度:44.333},{dateTime:新日期(1492019739661),纬度:23.2222,经度:44.333}]}]}))'

The latitudes and longitudes you see in the error are ones I'm trying to insert. 您在错误中看到的纬度和经度是我要插入的纬度和经度。

Any ideas on how to accomplish this? 关于如何做到这一点的任何想法?

Turns out I wasn't actually pushing to an array, this: 原来我实际上并没有推送到数组,这是:

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

should've been: 应该是:

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

Hope this might help someone in the future! 希望这对以后的人有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM