Итак, я все еще новичок в использовании MongoDB, поэтому я пытаюсь здесь подсчитать всех category
под productId
, у которых одна и та же категория. Таким образом, ожидаемый результат должен быть 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})
}
})
🤔 А знаете ли вы, что...
JavaScript позволяет создавать собственные серверные приложения с использованием платформы Node.js.
В агрегации коллекция для выполнения $lookup
должна быть products
(с s
), а не product
.
Имя коллекции, которую Mongoose создает в вашей базе данных, совпадает с именем вашей модели, за исключением строчных букв и множественного числа, как описано в документации.
Mongoose автоматически ищет строчную версию имени вашей модели во множественном числе. Таким образом, для приведенного выше примера модель Tank предназначена для коллекции танков в базе данных.
(выделение их)
При использовании платформы агрегации ваш конвейер агрегации отправляется в базу данных как есть. Mongoose не применяет к нему никаких принуждений или кастингов. Поэтому при написании конвейеров агрегации вы должны более или менее забыть, что используете Mongoose. Что важно, так это имя базовой коллекции в Mongo, которое генерируется из имени вашей модели на основе упомянутого правила.
При желании вы также можете самостоятельно переопределить имя коллекции, например:
export default mongoose.model('Product', ProductSchema, 'xyz');
Это переопределит поведение именования Mongoose по умолчанию и назовет коллекцию xyz
.