Spring Mongo DB @DBREF

时间:2017-05-30 10:21:46

标签: java mongodb spring-mongo spring-mongodb

这是我的MongoDb结构,

db.user.find();

用户:

{
"name" : "KSK", 
 "claim"  : [objectId("52ffc4a5d85242602e000000"),objectId("52ffc4a5d85242602e000001")] 
}
声称:

[
   {
     "_id" : "52ffc4a5d85242602e000001",
     "claimName" :"XXXX"
   },
   {
     "_id" : "52ffc4a5d85242602e000000",
     "claimName" :"YYY"
   }
]

我的实体课程是:

@Document(collection="user")
public  class User{
  @Id      
  private String id;
  private String name; 
  @DBRef
private List<Claim> claim; 
// setter and getter 

}

索赔类:

@Document(collection="Claim")
public class Claim{
   @Id 
   private String id; 
   private String claimName;   
}

我有一种方法可以通过以下名称获取用户,

public User findByName(String name);

如果我尝试点击此方法,则会收到错误,

找不到能够从类型org.bson.types.ObjectId转换为java.lang.String类型的转换器

所以我改变了我的用户实体类,如下所示,

而不是private List<Claim> claim;

更改为Private List<ObjectId> claim;

现在,如果我执行一个方法(findByName),我会得到一个同时具有声明对象ID的用户对象(&#34; 52ffc4a5d85242602e000001&#34;,&#34; 52ffc4a5d85242602e000000&#34;)然后迭代声明列表并获取与索赔对象Id相对应的索赔细节。

当我执行findByName方法时,我想获取用户并声明详细信息,而不是这样做。如何实现此功能

3 个答案:

答案 0 :(得分:3)

如果您使用@DBRef引用User类中的{ "name" : "KSK", "claim" : [ { "$ref":"claim", // the target collection "$id : "ObjectId("52ffc4a5d85242602e000000") } ] } ,则您的JSON不仅应包含ID,还应包含对集合的引用,以及在何处查找ID,如下所示:

 @DBRef List<Claim> claims;

这就是Spring-Data将您的Java对象映射到MongoDB的方式。如果你从一个空白数据库开始并让Spring创建并保存关系,你应该没有问题使用

class FloorWithTPCountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Floor
        fields = ('id', 'results')

    results = serializers.SerializerMethodField('get_tp_start')

    def get_tp_start(self, obj):
        query_params = self.context.get("request").query_params
        aggregations = {'hour':3600, 'day':86400, 'week':604800}
        if 'start' in query_params and 'end' in query_params:
            st_tm = int(query_params.get('start'))
            en_tm = int(query_params.get('end'))
            if 'aggregation' in query_params:
                aggregation_value = query_params.get('aggregation')
                aggregation = aggregations.get(aggregation_value)
            else:
                aggregation = en_tm - st_tm
            trackpoint_set = obj.trackpoint_set
            st = [{'count': trackpoint_set.filter(created_at__gte=ts, created_at__lt=ts + aggregation).values(
                'tag').distinct().count(), 'timestamp': ts} for ts in range(st_tm, en_tm, aggregation)]

        else:
            st = None
        return st

答案 1 :(得分:1)

我的建议是不要将Claim类设置为单独的@Document,或者只是切换回Relational Databases,因为它不是Mongo方法。 另外,如果你坚持使用当前的体系结构,你可以尝试在User.class中将List上面的@DBRef用于smth,如下所示:

public class ParentModel {

    @Id
    private String id;

    private String name;

    private ParentType parentType;

    private SubType subType;

    @DBRef
    private List<Model> models;

....
}

答案 2 :(得分:0)

作为@DBRef的替代方法,请查看RelMongo(link) 这提供了一种管理关系的有力方法,在您的情况下,将像这样:

@OneToMany(fetch = FetchType.LAZY)
private list<Claim> claims;