通过 Morphia 推送到嵌入式子文档中的数组 (MongoDB)
Pushing to array in embedded subdocument via Morphia (MongoDB)
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
}
最后,地戳对象如下所示:
@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 数组中。
我认为可以通过以下方式完成:
我的查询(是的,我知道 retrievedFields 已被弃用,我不想使用它,但这是我最接近工作的解决方案):
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);
最后,更新结果:
final UpdateResults trackerUpdateResults = datastore.update(trackerQuery, trackerUpdate);
这将引发 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 } ] } ]})'
您在错误中看到的纬度和经度是我要插入的。
关于如何实现这个的任何想法?
事实证明我实际上并没有推送到一个数组,这个:
final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class).push("days.geoStamps", newGeoStamps);
应该是:
final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class)
.push("days.$.geoStamps", newGeoStamps);
希望这对以后的人有所帮助!
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
}
最后,地戳对象如下所示:
@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 数组中。
我认为可以通过以下方式完成:
我的查询(是的,我知道 retrievedFields 已被弃用,我不想使用它,但这是我最接近工作的解决方案):
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);
最后,更新结果:
final UpdateResults trackerUpdateResults = datastore.update(trackerQuery, trackerUpdate);
这将引发 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 } ] } ]})'
您在错误中看到的纬度和经度是我要插入的。
关于如何实现这个的任何想法?
事实证明我实际上并没有推送到一个数组,这个:
final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class).push("days.geoStamps", newGeoStamps);
应该是:
final UpdateOperations<Tracker> trackerUpdate = datastore.createUpdateOperations(Tracker.class)
.push("days.$.geoStamps", newGeoStamps);
希望这对以后的人有所帮助!