Mongoose, как использовать .add для повторного использования схемы с виртуальной - PullRequest
1 голос
/ 08 ноября 2019

У меня есть сценарий использования, в котором я хочу определить схему с виртуальной, а затем использовать эту схему в нескольких местах. Для этого я нашел свойство .add в документации mongoose, как показано здесь .

Поведение это не то, что я ожидаю, хотя по умолчанию виртуальное не заполняется. Я посмотрел на конкретную сгенерированную схему и обнаружил, что после ее создания с помощью «.add» она не сохраняет все поля исходной схемы. В частности, в объекте "virtuals" свойство "path" становится пустым объектом вместо строки, а в объекте "tree" виртуальное отсутствует вообще.

Я просмотрел фактическую зависимость и обнаружил, что эторезультат того, как «.add» работает внутри, а именно вызывает функцию «слияние», которая копирует многие свойства в новую схему. Примечательно, что функция слияния ничего не делает с объектом «дерево» в схеме, а в случае виртуалов она копирует имя / options / getters / setters, но ничего не делает для «пути». Я вручную добавил недостающие части в функцию слияния, и это исправило мою проблему, но я хотел бы знать, просто ли я использую это неправильно или это ошибка в библиотеке mongoose, поскольку непосредственное обновление зависимости не являетсяправильное решение для меня.

Вот пример того, как я создаю экземпляры схем

const testBase= data.db.Schema({
    test: {type: String, required: true}
});
testBase.virtual('testVirtual')
.get(function () {
    return "test";
});
testBase.set('toObject', {virtuals: true});
testBase.set('toJSON', {virtuals: true});

const testParent = data.db.Schema();
testParent.add(testBase);
testParent.set('toObject', {virtuals: true});
testParent.set('toJSON', {virtuals: true});

В этом примере, если я использую "testBase" в качестве моей схемы в модели, она будет правильно использоватьвиртуальный, в то время как если я использую «testParent», он не будет. Когда я ожидаю, что они должны вести себя одинаково.

Получение JSON двух схем показывает это для testBase

{
"$id": 24,
"_indexes": [],
"_userProvidedOptions": {
    "toJSON": {
        "virtuals": true
    },
    "toObject": {
        "virtuals": true
    }
},
"aliases": {},
"callQueue": [],
"childSchemas": [],
"inherits": {},
"methodOptions": {},
"methods": {},
"nested": {},
"obj": {
    "test": {
        "required": true
    }
},
"options": {
    "_id": true,
    "autoIndex": null,
    "bufferCommands": true,
    "capped": false,
    "discriminatorKey": "__t",
    "id": true,
    "minimize": true,
    "noId": false,
    "noVirtualId": false,
    "read": null,
    "shardKey": null,
    "strict": true,
    "toJSON": {
        "virtuals": true
    },
    "toObject": {
        "virtuals": true
    },
    "typeKey": "type",
    "validateBeforeSave": true,
    "versionKey": "__v"
},
"paths": {
    "_id": {
        "$immutable": null,
        "_index": null,
        "getters": [],
        "instance": "ObjectID",
        "options": {
            "auto": true
        },
        "path": "_id",
        "setters": [
            null
        ],
        "validators": []
    },
    "test": {
        "$immutable": null,
        "_index": null,
        "enumValues": [],
        "getters": [],
        "instance": "String",
        "isRequired": true,
        "options": {
            "required": true
        },
        "originalRequiredValue": true,
        "path": "test",
        "regExp": null,
        "setters": [],
        "validators": [
            {
                "message": "Path `{PATH}` is required.",
                "type": "required"
            }
        ]
    }
},
"plugins": [],
"query": {},
"s": {
    "hooks": {
        "_posts": {},
        "_pres": {}
    }
},
"singleNestedPaths": {},
"statics": {},
"subpaths": {},
"tree": {
    "_id": {
        "auto": true
    },
    "test": {
        "required": true
    },
    "testVirtual": {
        "getters": [
            null
        ],
        "options": {},
        "path": "testVirtual",
        "setters": []
    }
},
"virtuals": {
    "testVirtual": {
        "getters": [
            null
        ],
        "options": {},
        "path": "testVirtual",
        "setters": []
    }
}

}

И это для testParent

{
"$id": 25,
"_indexes": [],
"_userProvidedOptions": {
    "toJSON": {
        "virtuals": true
    },
    "toObject": {
        "virtuals": true
    }
},
"aliases": {},
"callQueue": [],
"childSchemas": [],
"inherits": {},
"methodOptions": {},
"methods": {},
"nested": {},
"options": {
    "_id": true,
    "autoIndex": null,
    "bufferCommands": true,
    "capped": false,
    "discriminatorKey": "__t",
    "id": true,
    "minimize": true,
    "noId": false,
    "noVirtualId": false,
    "read": null,
    "shardKey": null,
    "strict": true,
    "toJSON": {
        "virtuals": true
    },
    "toObject": {
        "virtuals": true
    },
    "typeKey": "type",
    "validateBeforeSave": true,
    "versionKey": "__v"
},
"paths": {
    "_id": {
        "$immutable": null,
        "_index": null,
        "getters": [],
        "instance": "ObjectID",
        "options": {
            "auto": true
        },
        "path": "_id",
        "setters": [
            null
        ],
        "validators": []
    },
    "test": {
        "$immutable": null,
        "_index": null,
        "enumValues": [],
        "getters": [],
        "instance": "String",
        "isRequired": true,
        "options": {
            "required": true
        },
        "originalRequiredValue": true,
        "path": "test",
        "regExp": null,
        "setters": [],
        "validators": [
            {
                "message": "Path `{PATH}` is required.",
                "type": "required"
            }
        ]
    }
},
"plugins": [],
"query": {},
"s": {
    "hooks": {
        "_posts": {},
        "_pres": {}
    }
},
"singleNestedPaths": {},
"statics": {},
"subpaths": {},
"tree": {
    "_id": {
        "auto": true
    },
    "test": {
        "required": true
    }
},
"virtuals": {
    "testVirtual": {
        "getters": [
            null
        ],
        "options": {},
        "path": {},
        "setters": []
    }
}

} ​​

Если вы сравните отсутствующие схемы, вы увидите, какие поля отсутствуют. Если кто-нибудь знает правильный способ использования этой функциональности или примеров в этом направлении, я был бы признателен. (Мое тестирование проводилось с версией mongoose 5.7.8)

...