Spring Data MongoRepository сохраняет объекты с различным количеством полей

Я храню игровые состояния в базе данных MongoDB и использую Spring Data для управления взаимодействием с базой данных. Я новичок в Spring Data и не уверен, как справиться со следующим сценарием.

У меня есть документ типа «Игра» с множеством свойств, таких как id, timestamp и т. Д. Одно из этих свойств - это список действий, предпринятых пользователями. Эти действия имеют форму:

{ type: 2 }, {type: 3, value: 4}, {type: 5, id: 1234}, {type 6}, {type: 5, value: 6, id: 56}

Другими словами, действие может иметь три свойства: тип, значение и идентификатор. Однако не каждое действие требует сохранения всех трех значений. Я хочу избежать кучи нулевых значений в моей базе данных и хотел бы, чтобы моя база данных просто не включала и id, или значение, если они не указаны.

Используя модель Spring Data MongoRepository, я не уверен, как этого добиться. Я могу создать класс CRUD Game и иметь одно из его свойств в виде списка Action (где само действие является классом CRUD с типом свойств, значением и идентификатором), но не приведет ли это к сохранению нулевых значений в базе данных, если Я не указываю значение или id?

Короче говоря, как я могу использовать Spring Data MongoRepository, но при этом сохранять гибкость, имея возможность хранить списки объектов с различными параметрами или типами объектов в целом.


person user2779450    schedule 18.06.2020    source источник
comment
Вы пробовали использовать Map ‹String, Integer›. Это может помочь вам решить вашу проблему   -  person Silverfang    schedule 18.06.2020


Ответы (1)


Я объясню, как обрабатываются различные поля на примере. Следующий класс Game.java POJO представляет отображение объекта в game документ коллекции.

public class Game {

    String name;
    List<Actions> actions;

    public Game(String name, List<Actions> actions) {
        this.name = name;
        this.actions = actions;
    }

    public String getName() {
        return name;
    }

    public List<Actions> getActions() {
        return actions;
    }

    // other get/set methods, override, etc..


    public static class Actions {

        Integer id;
        String type;

        public Actions() {
        }

        public Actions(Integer id) {
            this.id = id;
        }

        public Actions(Integer id, String type) {
            this.id = id;
            this.type = type;
        }

        public Integer getId() {
            return id;
        }

        public String getType() {
            return type;
        }

        // other methods
    }
}

Для класса Actions вам необходимо предоставить конструкторам возможные комбинации. Используйте соответствующий конструктор с id, type и т. Д. Например, создайте объект Game и сохраните его в базе данных:

Game.Actions actions= new Game.Actions(new Integer(1000));
Game g1 = new Game("G-1", Arrays.asList(actions));
repo.save(g1);

Он хранится в коллекции базы данных game следующим образом (запрашивается из mongo оболочки):

{
        "_id" : ObjectId("5eeafe2043f875621d1e447b"),
        "name" : "G-1",
        "actions" : [
                {
                        "_id" : 1000
                }
        ],
        "_class" : "com.example.demo.Game"
}

Обратите внимание на массив actions. Поскольку мы сохранили только поле id в объекте Game.Actions, сохраняется только это поле. Несмотря на то, что вы указываете все поля в классе, сохраняются только те, которые имеют значения.

Это еще два документа, в которых Game.Actions создано только с type и id + type с использованием соответствующих конструкторов:

{
        "_id" : ObjectId("5eeb02fe5b86147de7dd7484"),
        "name" : "G-9",
        "actions" : [
                {
                        "type" : "type-x"
                }
        ],
        "_class" : "com.example.demo.Game"
}
{
        "_id" : ObjectId("5eeb034d70a4b6360d5398cc"),
        "name" : "G-11",
        "actions" : [
                {
                        "_id" : 2,
                        "type" : "type-y"
                }
        ],
        "_class" : "com.example.demo.Game"
}
person prasad_    schedule 18.06.2020
comment
Важна ли статическая природа класса Action? Или я мог бы просто создать новый нестатический класс под названием Action с этими двумя конструкторами? Кроме того, означает ли это, что свойства с нулевыми значениями (т.е. свойства, которые не были инициализированы) не будут включены при сохранении в базу данных? - person user2779450; 18.06.2020
comment
(1) Вы можете создать другой класс Actions. Статический вложенный класс связан с охватывающим (внешним) классом. (2) Поля с неназначенными значениями и с нулевыми значениями по умолчанию не хранятся в базе данных (как показано в примере). Это верно для любого класса Pojo, отображаемого в документ коллекции. - person prasad_; 19.06.2020