如何使用 Spring 数据 Mongo 映射器和复合键指定键参数顺序

How to specify key param order using Spring Data Mongo Mapper and composite key

我有一个 POJO,我想使用复合键来支持多区域 mongo 分布,使用首先在区域上然后在 object id 上完成分片。为此,我创建了以下 POJO:

@Document("users")
public class User {
    @Id
    private Key id;
    ... // other irrelevant fields + getters/setters
}

密钥 class 如下所示:

// Note the order of fields is region, then id
public class Key implements Serializable {
    private final @NotNull String region;
    private final @NotNull String id;
    public Key(@NotNull String region, @NotNull String id) {
        this.region = region;
        this.id = id;
    }
}

不幸的是,当 Spring 数据映射器将其转换为文档时,结果如下:

{ "_id" : { "_id" : "12345", "region" : "us_west" } }

当我期待这个时(由于数据库分片很重要):

{ "_id" : { "region" : "us_west", "_id" : "12345" } }

我观察到的一件事是,映射器似乎将任何标题为 "id" 的 Java 字段转换为“_id”,并自动将它们移至第一个。如果可能的话,这正是我想避免的。我发现的一种解决方法是将密钥的第二部分重命名为 "id2",如下所示:

public class Key implements Serializable {
    private final @NotNull String region;
    private final @NotNull String id2;
    public Key(@NotNull String region, @NotNull String id2) {
        this.region = region;
        this.id2 = id2;
    }
}

这给了我一个可行的解决方案,结果是:

{ "_id" : { "region" : "us_west", "id2" : "12345" } }

...但是理想情况下,我不想重命名字段,因为它会影响我代码的其他区域,所以我想知道是否有一种方法可以通过注释为映射器指定字段的顺序或者强制执行 POJO 声明顺序,这是我首先期望发生的事情?

我发现 @Field 注释做了我需要的。在这种情况下,仅使用 order 参数是不够的,因为自从 Mongo 映射器将 id 重命名为 _id 后,它还将 属性 放在首位。一旦我将显式持久性值参数添加为 id 然后一切都按预期工作。

public class Key implements Serializable {
    @Field(order = 1)
    private final @NotNull String region;
    @Field(value = "id", order = 2)
    private final @NotNull String id;
    public Key(@NotNull String region, @NotNull String id) {
        this.region = region;
        this.id = id;
    }
}

这是持久化的 mongo 文档:

{ "_id" : { "region" : "us_west", "id" : "12345" } }