Spring MongoDB手册参考



我试图在Spring MongoDB中创建手动引用,只需在引用字段中存储一个ObjectId,并仅在需要时填充它。(即无DBRef(

然而,我一直找不到关于如何正确实现这一点的文档。

假设我有一个像这样的简单模型:


@Document(collection = "person")
public class Person{
@Id
private String id;
... other attributes
//This is a reference to Address model
private ObjectId address;
}

@Document(collection = "address")
public class Address{
@Id
private String id;
... other attributes
}

我如何在这里创建手动引用,只将地址模型的ID存储在Person中,然后只在需要时填充?

更新:为了澄清,我们已经在数据库中有很多以前使用Mongoose插入的文档,其中模型a包含引用模型B的ObjectId。使用monoose,我们可以在需要时对这些文档调用.populate。然后当我们保存文档时,Mongoose只保存了ObjectId。

基本上,我正在尝试在Spring中实现一个类似的系统。我创建了一个自定义转换器,在加载数据时将ObjectId转换为特定类型,但此解决方案没有帮助,因为它在保存时不会将Model转换为ObjectId。

以下是我们需要的:

  1. 引用字段仅包含一个ObjectID或一个ID数组
  2. 我们只能在需要时填充字段
  3. 我们可以修改填充的字段并调用save方法,该方法会更新两个文档,并且只将ObjectId保存在引用字段中
  4. 某些文档的"引用"字段可以为空
  5. 添加新引用时,我们可以使用ObjectID或对象。在任何一种情况下,都应该只使用ObjectID

同样,这正是Javascript中Mongoose的工作方式,也是我们目前正在使用的。

我正在寻找一个详细的答案或某种教程来解释如何实现这一点,因为我找不到任何使用手动参考的例子,这很奇怪,因为手动参考是更流行和推荐的方法。

使用@DbRef并使用相同的字段名,只是引用ObjectId列表作为模型上的另一个字段。

public class ModelModelListener extends AbstractMongoEventListener<Model> {
@Override
public void onBeforeSave(BeforeSaveEvent<Model> event) {
final Model source = event.getSource();
final Document document = event.getDocument();
final List<Model> modelList = source.getModelList();
final List<ObjectId> modelIdList = source.getModelIdList();
if (document != null)
document.put("modelList", modelList != null ? toIdList(modelList) : modelIdList);
}
@Override
public void onAfterConvert(AfterConvertEvent<Model> event) {
final Model source = event.getSource();
final Document document = event.getDocument();
if (document != null)
source.setModelIdList(document.getList("modelList", ObjectId.class));
}
}
@Data // Lombok getter setter
@Document
public class Model {
@Field("modelList")
@DBRef(lazy = true)
private List<Model> modelList;
@Field
private List<ObjectId> modelIdList;
}

或者,您可以在更新或插入时使用带有条件的MongoTemplate。

final Update update = new Update();
update.push("field", modelB.getId());
mongoTemplate.updateFirst(query, update, ModelA.class);

您可以修改find方法。

db.person.find({...parameters...}).forEach(function(persons) {
persons.forEach(p => {
db.address.find({person: p.id}).forEach(function(address) {
person.address = address.id;
});
});

这样做时,您总是传递关系ID。我相信没有DBRef是不可能的。

最新更新