【发布时间】:2020-01-02 00:48:20
【问题描述】:
我正在做一个项目,需要通过子文档_id 从模型中检索特定的子文档。然后我计划对这些子文档进行更新并保存主文档。 mongoose 子文档文档列出了您可以在 parent.children 数组上调用的许多方法,但是 Javascript 中尚不存在数组的方法会给出错误消息,指出它们不存在且无法编译。我正在参考这个文档:https://mongoosejs.com/docs/subdocs.html
我知道应该能够使用.findOneAndUpdate 进行更新,并且使用runValidators 选项仍然应该验证所有内容,但我也想只检索子文档本身。
我查看了这篇文章:MongoDB, Mongoose: How to find subdocument in found document?,我将评论说,如果注册了子文档架构,它会自动为该架构创建一个集合,该集合仅在单独保存该架构时才会创建。您不能使用ChildModel.findOne() 来检索子文档,因为该集合不存在,其中没有任何内容。
拥有IChildModel 扩展mongoose.Types.Subdocument 并拥有IParent 接口引用而不是IChild 并且不注册ChildModel 除了不再允许对.push() 的调用不接受简单之外没有任何改变对象(缺少 30 个左右的属性)。同样在IParent 接口中使用此方法尝试mongoose.Types.Array<IChild> 不会改变任何内容。
将IParent 接口更改为将mongoose.Types.Array<IChild> 用于children 属性允许addToSet() 工作,但不允许id() 或create() 工作
我正在使用 Mongoose 版本 5.5.10、MongoDb 版本 4.2.0 和 Typescript 版本 3.4.5
import mongoose, { Document, Schema } from "mongoose";
// Connect to mongoDB with mongoose
mongoose.connect(process.env.MONGO_HOST + "/" + process.env.DB_NAME, {useNewUrlParser: true, useFindAndModify: false});
// Interfaces to be used throughout application
interface IParent {
name: string;
children: IChild[];
}
interface IChild {
name: string;
age: number;
}
// Model interfaces which extend Document
interface IParentModel extends IParent, Document { }
interface IChildModel extends IChild, Document { }
// Define Schema
const Child: Schema = new Schema({
name: {
type: String,
required: true
},
age: {
type: Number,
required: true
}
});
const ChildSchema: Schema = Child;
const Parent: Schema = new Schema({
name: {
type: String,
required: true
},
children: [ChildSchema]
});
const ParentSchema: Schema = Parent;
// Create the mongoose models
const ParentModel = mongoose.model<IParentModel>("Parent", Parent);
const ChildModel = mongoose.model<IChildModel>("Child", Child);
// Instantiate instances of both models
const child = new ChildModel({name: "Lisa", age: 7});
const parent = new ParentModel({name: "Steve", children: [child]});
const childId = child._id;
// Try to use mongoose subdocument methods
const idRetrievedChild = parent.children.id(childId); // Property 'id' does not exist on type 'IChild[]'.ts(2339)
parent.children.addToSet({ name: "Liesl", age: 10 }); // Property 'addToSet' does not exist on type 'IChild[]'.ts(2339)
parent.children.create({ name: "Steve Jr", age: 2 }); // Property 'create' does not exist on type 'IChild[]'.ts(2339)
// If I always know the exact position in the array of what I'm looking for
const arrayRetrievedChild = parent.children[0]; // no editor errors
parent.children.unshift(); // no editor errors
parent.children.push({ name: "Emily", age: 18 }); // no editor errors
【问题讨论】:
标签: mongodb typescript mongoose