所以我仍然是新的使用MongoDB,所以我在这里要做的是计数所有productId
下的category
,它们具有相同的类别。所以期望输出应该是7
。我首先使用填充,但卡住了我如何使用$count
。相反,我使用aggregate
,然后使用$lookup
,但我只有product
的空数组
CartSchema.js
const CartSchema = new mongoose.Schema({
productId: {type: mongoose.Schema.Types.ObjectId, ref: 'Product'}
})
export default mongoose.model('Cart', CartSchema)
ProductSchema.js
const ProductSchema = new mongoose.Schema({
category: {type: String, required: true},
})
export default mongoose.model('Product', ProductSchema)
我使用这段代码来显示productId
下的信息。
router.get('/categories', async (req, res) => {
try {
const cart = await Cart.find()
.populate([
{path: 'productId', select: 'category' },
]).exec()
res.status(200).json(cart);
} catch (error) {
res.status(500).json({error: error.message})
}
})
填充方法的结果。
[
{
"_id": "63b410fdde61a124ffd95a51",
"productId": {
"_id": "63b410d6de61a124ffd9585b",
"category": "CASE"
},
},
{
"_id": "63b41a679950cb7c5293bf12",
"productId": {
"_id": "63b41637e3957a541eb59e81",
"category": "CASE"
},
},
{
"_id": "63b433ef226742ae6b30b991",
"productId": {
"_id": "63b41637e3957a541eb59e81",
"category": "CASE"
},
},
{
"_id": "63b670dc62b0f91ee4f8fbd9",
"productId": {
"_id": "63b410d6de61a124ffd9585b",
"category": "CASE"
},
},
{
"_id": "63b6710b62b0f91ee4f8fc13",
"productId": {
"_id": "63b410d6de61a124ffd9585b",
"category": "CASE"
},
},
{
"_id": "63b671bc62b0f91ee4f8fc49",
"productId": {
"_id": "63b410d6de61a124ffd9585b",
"category": "CASE"
},
},
{
"_id": "63b6721c62b0f91ee4f8fcc5",
"productId": {
"_id": "63b410d6de61a124ffd9585b",
"category": "CASE"
},
]
所以我使用了这个方法,但我得到的只是一个空数组
router.get('/categories', async (req, res) => {
try {
const cart = await Cart.aggregate([
{
$lookup: {
from: 'product',
localField: 'productId',
foreignField: '_id',
as: 'product'
}
},
{
$unwind: "$product"
},
{
$group: {
_id: "$product.category",
total: {
$sum: 1
}
}
},
{
$sort: {total: -1}
},
{
$project: {
_id: 0,
category: "$_id",
total: 1
}
},
])
res.status(200).json(cart);
} catch (error) {
res.status(500).json({error: error.message})
}
})
在聚合中,要执行$lookup
的集合应该是products
(带有一个s
),而不是product
。
Mongoose在数据库中创建的集合的名称与模型的名称相同,除了小写和复数,如文档中所述。
Mongoose自动查找您的模型名称的复数,小写版本。因此,对于上面的例子,模型Tank是针对坦克
(并强调了这一点)使用聚合框架时,聚合管道按原样发送到数据库。猫鼬不会对它做任何强制或施法。因此,在编写聚合管道时,您应该或多或少忘记使用的是Mongoose。重要的是Mongo中底层集合的名称,它是根据上述规则从模型名称生成的。
如果需要,也可以自己重写集合名称,例如:
export default mongoose.model('Product', ProductSchema, 'xyz');
这将覆盖Mongoose的默认命名行为,将集合命名为xyz
。