嵌套Java类中的id属性,映射为MongoDb ObjectId()

时间:2018-06-25 09:36:32

标签: spring-data-mongodb

以下结构:

@Document 
public class Palace {
    @Id
    private String id;
    private Location location;
    // additional attributes, getter, setter 
}

public class Location {
    private String id;
    // additional attributes, getter, setter
}

据我了解ObjectId的概念,在MongoDB文档中只能有一个ObjectId(_id),并且它必须在文档的根目录下。但是当通过Spring Boot 1.5.14插入数据时,我得到以下结构:

{
    "_id" : ObjectId("5b05387a8db58e0001d38851"),
    "location" : {
        "_id" : ObjectId("5ae712d1b2b197000132cd9b"),
    }
}

我的问题是:这是spring-data-mongo中的预期行为吗?我本来期望以下结构:

{
    "_id" : ObjectId("5b05387a8db58e0001d38851"),
    "location" : {
        "id" : "5ae712d1b2b197000132cd9b",
    }
}

如果我用@Field注释位置ID

public class Location {
    @Field("id")
    private String id;
    // additional attributes, getter, setter
}

然后按预期保存文档,但使用存储库方法查询

getPalaceByLocationId()

不会给出任何结果。

1 个答案:

答案 0 :(得分:0)

id字段的一些见解。在spring-data-mongodb中,对id字段的处理有些不同。

签出documentation

当您声明这样的ID时,扩展您案例的文档

public class Location {
    private String id;
    // additional attributes, getter, setter
}

它以_id的形式存储在数据库中。您可以通过查看数据库来进行交叉检查。用@Id

注释时也是如此
{
    "_id" : ObjectId("5b31fad36a19cc45db205056"),
    "location" : {
        "_id" :  ObjectId("5ae712d1b2b197000132cd9b")
    }
}

5ae712d1b2b197000132cd9b是您使用location.setId()设置的ID。在内部将其转换为ObjectId并存储为_id

但是,当您添加@Field批注时,情况会发生变化。假设您添加了这样的注释

@Field("id")
private String id;

然后该文档在数据库中看起来像这样。

{
    "_id" : ObjectId("5b31fad36a19cc45db205056"),
    "location" : {
        "id" :  "5ae712d1b2b197000132cd9b"
    }
}

问题是您无法通过ID进行检索。因为当你写  findPalaceByLocationIdfindByLocation_Id(弹簧数据)尝试查找不存在的_id字段。

解决这个问题的唯一方法就是像这样

@Field
private String id;

或者只是

private String id;

这将在数据库中创建_id,您可以执行findByLocationId

我知道这有点粗略。但这就是它的工作原理。

关于

  

据我了解ObjectId的概念,只能有一个   MongoDB文档中的ObjectId(_id),并且必须位于根级别   文档。

那是不正确的。

有关映射的小信息表

Field definition         Resulting Id-Fieldname in MongoDB  

String id                      _id  
@Field String id               _id  
@Field('x') String id           x    
@Field('id') String id          id (InAccessible)   
@Id String x                   _id  
@Field('x') @Id String x       _id