创建连接
单个连接
mongoose.connect('mongodb://127.0.0.1:27017/myapp')
mongoose.connect('mongodb://username:password@host:port/database?options...')
多个连接
const conn = mongoose.createConnection('mongodb://127.0.0.1:27017/myapp')
conn.asPromise() // 连接成功
建立schema
嵌套对象定义
interface Inventory {
item: string
qty: number
size?: { h: number; w?: number; uom?: string }
status: string
}
const inventorySchema = new mongoose.Schema<Inventory>(
{
item: { type: String, required: true },
qty: { type: Number, required: true },
size: {
h: { type: Number, required: true },
w: Number,
uom: String
},
status: { type: String, required: true },
},
{ versionKey: false },
)
注意:当字段名为
type时,必需再嵌套一层type指定其类型,否则type字段会被识别成类型隐患:当插入文档时,如果不提供
size字段,会出现以下错误:Error: Inventory validation failed: size.h: Path
size.his required.理论上
size是非必需字段才对呀
嵌套对象定义(嵌套对象字段不必需,但对象里的某个属性必需)
interface Inventory {
item: string
qty: number
size?: { h: number; w?: number; uom?: string }
status: string
}
const inventorySchema = new mongoose.Schema<Inventory>(
{
item: { type: String, required: true },
qty: { type: Number, required: true },
size: {
type: { h: { type: Number, required: true }, w: Number, uom: String },
_id: false
},
status: { type: String, required: true },
},
{ versionKey: false },
)
为什么需要
_id: false?当使用
type定义嵌套对象类型时,等同于嵌入了一个子文档(定义方式如下),子文档和文档都必须包含_id属性,如果你不需要_id,需要手动指定为false
子文档定义
interface InventorySize {
h: number
w: number
uom: string
}
interface Inventory {
item: string
qty: number
size: InventorySize
status: string
}
const inventorySizeSchema = new mongoose.Schema<InventorySize>(
{
h: { type: Number, required: true },
w: Number,
uom: String,
},
{ _id: false },
)
const inventorySchema = new mongoose.Schema<Inventory>(
{
item: { type: String, required: true },
qty: { type: Number, required: true },
size: inventorySizeSchema,
status: { type: String, required: true },
},
{ versionKey: false },
)
建立model
const inventoryModel = mongoose.model('Inventory', inventorySchema, 'inventory')
const inventoryModel = conn.model('Inventory', inventorySchema, 'inventory')
查询
对嵌入/嵌套文档的查询
await inventoryModel.insertMany([
{
item: 'journal',
qty: 25,
size: { h: 14, w: 21, uom: 'cm' },
status: 'A'
},
{
item: 'notebook',
qty: 50,
size: { h: 8.5, w: 11, uom: 'in' },
status: 'A'
},
{
item: 'paper',
qty: 100,
size: { h: 8.5, w: 11, uom: 'in' },
status: 'D'
},
{
item: 'planner',
qty: 75,
size: { h: 22.85, w: 30, uom: 'cm' },
status: 'D'
},
{
item: 'postcard',
qty: 45,
size: { h: 10, w: 15.25, uom: 'cm' },
status: 'A'
}
]);
以下示例使用该
inventory集合
使用点表示法 查询嵌套字段
await inventoryModel.find({ 'size.uom': 'in' })
选择嵌套在
size字段中的字段uom等于"in"的所有文档
await inventoryModel.find({ 'size.h': { $lt: 15 } })
选择嵌套在
size字段中的字段h小于15的所有文档
匹配嵌入/嵌套的文档
await inventoryModel.find({ size: { h: 14, w: 21, uom: 'cm' } })
选择字段
size等于文档 { h: 14, w: 21, uom: "cm" } 的所有文档
警告:MongoDB不建议在嵌入式文档上进行相等匹配,因为操作需要指定
<value>文档的精确匹配,包括字段顺序。
查询数组
await inventoryModel.insertMany([
{
item: 'journal',
qty: 25,
tags: ['blank', 'red'],
dim_cm: [14, 21]
},
{
item: 'notebook',
qty: 50,
tags: ['red', 'blank'],
dim_cm: [14, 21]
},
{
item: 'paper',
qty: 100,
tags: ['red', 'blank', 'plain'],
dim_cm: [14, 21]
},
{
item: 'planner',
qty: 75,
tags: ['blank', 'red'],
dim_cm: [22.85, 30]
},
{
item: 'postcard',
qty: 45,
tags: ['blue'],
dim_cm: [10, 15.25]
}
]);
以下示例使用该
inventory集合
匹配数组
await inventoryModel.find({ tags: ['red', 'blank'] })
查询字段
tags值为数组,且 恰好 包含red和blank两个元素(包括元素的顺序)的所有文档
await inventoryModel.find({ tags: { $all: ['red', 'blank'] } })
查询字段
tags值为数组,且包含red和blank两个元素(不考虑元素的顺序或其他元素)的所有文档
在数组中查询元素
await inventoryModel.find({ tags: 'red' })
查询字段
tags为数组,且包含字符串red作为其中一个元素的所有文档
为数组元素指定多个条件
await return inventoryModel.find({ dim_cm: { $gt: 15, $lt: 20 } })
查询文档,其中
dim_cm数组包含以某种方式组合满足查询条件的元素;例如,一个元素可以满足大于15条件,另一个元素可以满足小于20条件,或者单个元素可以同时满足(个人感觉基本用不到。。。)
await return inventoryModel.find({ dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } })
查询
dim_cm数组中至少有一个元素大于22且小于30的所有文档
await return inventoryModel.find({ 'dim_cm.1': { $gt: 25 } })
查询
dim_cm数组中第二个元素大于25的所有文档
await return inventoryModel.find({ tags: { $size: 3 } })
查询
tags数组中包含3个元素的所有文档
查询嵌入文档的数组
await inventoryModel.insertMany([
{
item: 'journal',
instock: [
{ warehouse: 'A', qty: 5 },
{ warehouse: 'C', qty: 15 }
]
},
{
item: 'notebook',
instock: [{ warehouse: 'C', qty: 5 }]
},
{
item: 'paper',
instock: [
{ warehouse: 'A', qty: 60 },
{ warehouse: 'B', qty: 15 }
]
},
{
item: 'planner',
instock: [
{ warehouse: 'A', qty: 40 },
{ warehouse: 'B', qty: 5 }
]
},
{
item: 'postcard',
instock: [
{ warehouse: 'B', qty: 15 },
{ warehouse: 'C', qty: 35 }
]
}
]);
匹配嵌套在数组中的文档
await inventoryModel.find({ instock: { warehouse: 'A', qty: 5 } })
查询
instock数组中元素与指定文档匹配的所有文档(整个嵌入/嵌套文档上的相等匹配要求指定文档的完全匹配,包括字段顺序)
在文档数组中的字段上指定查询条件
await inventoryModel.find({ 'instock.qty': { $lte: 20 } })
查询
instock数组中至少有一个嵌入文档包含qty字段,且值小于或等于20的所有文档
await inventoryModel.find({ 'instock.0.qty': { $lte: 20 } })
查询
instock数组中的第一个元素包含qty字段,且值小于或等于20的所有文档
为文档数组指定多个条件
await inventoryModel.find({ instock: { $elemMatch: { qty: 5, warehouse: 'A' } } })
查询
instock数组中至少有一个嵌入文档,包含qty字段等于5和warehouse字段等于A的所有文档
await inventoryModel.find({ 'instock.qty': { $gt: 10, $lte: 20 } })
查询匹配任何嵌套在
instock数组中的文档的qty字段大于10,且数组中任何文档(但不一定是相同的嵌入文档)的qty字段小于或等于20的所有文档(跟前面为数组元素指定多个条件类似。。。)