Spring MongoDB 手册参考

Spring MongoDB manual reference

我正在尝试在 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。使用 mongoose 我们可以在需要时对这些调用 .populate。然后当我们保存文档时,Mongoose 只保存了 ObjectId。

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

这是我们需要的:

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

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

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

您可以修改查找方法。

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.

就没有办法

使用@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);