Javascript Mongoose:按对象id分组并推入一个数组,按createdAt排序,填充所有对象并分页
这是一个按每页10项获取到达列表的示例:Javascript Mongoose:按对象id分组并推入一个数组,按createdAt排序,填充所有对象并分页,javascript,node.js,mongoose,pagination,aggregate,Javascript,Node.js,Mongoose,Pagination,Aggregate,这是一个按每页10项获取到达列表的示例: router.get('/arrivals', isAuthenticated, async (request, response, next) => { jsonPreProcessor.response = response; const resPerPage = 10; const page = request.query.page || 1; Arrival.find({}) .populate({
router.get('/arrivals', isAuthenticated, async (request, response, next) => {
jsonPreProcessor.response = response;
const resPerPage = 10;
const page = request.query.page || 1;
Arrival.find({})
.populate({
path: 'product',
populate: {
path: 'type'
}
})
.select('-__v')
.skip((resPerPage * page) - resPerPage)
.limit(resPerPage).then(arrivals => {
Arrival.countDocuments({}).then(numberOfResults => {
return jsonPreProcessor.paginate(arrivals, page, Math.ceil(numberOfResults / resPerPage), numberOfResults);
}).catch(error => {
return jsonPreProcessor.error(error.message);
});
}).catch(error => {
return jsonPreProcessor.error(error.message);
});
});
这是一个输出:
{
"time": "2020-01-16T10:11:22.588Z",
"message": "success",
"success": true,
"data": {
"list": [
{
"quantity": 1,
"discount": 0,
"_id": "5e0db80a37dd4437b4329960",
"product": {
"_id": "5e0cecaaa9a5cc2c7c62e379",
"title": "Ортопедический",
"type": {
"_id": "5ddcbc4685e53838dc564a44",
"title": "fsdkjhfs",
"createdAt": "2019-11-26T05:46:46.797Z",
"updatedAt": "2019-11-26T05:46:46.797Z",
"alt": "fsdkjhfs",
"__v": 0
},
...
"mode": "simple",
"createdAt": "2020-01-01T19:02:02.840Z",
"updatedAt": "2020-01-01T19:02:02.840Z",
"alt": "ortopedicheskij",
"__v": 0
},
...
"sellPrice": 6,
"minSellPrice": 0,
"createdAt": "2020-01-02T09:29:46.688Z",
"updatedAt": "2020-01-13T09:30:26.126Z"
},
... // And other 9 items
],
"currentPage": 1,
"pages": 2,
"numberOfResults": 16,
"incompleteResults": true
},
"type": null
}
所有这些都是到货,正如你们看到的,到货有产品。有些到货可以有相同的产品(按id)我的问题是将具有相同产品的到达者分组。(按到达数组的第一项排序)填充所有对象。。和分页。我使用聚合,不幸的是我不知道如何使用它(首先聚合的输出是随机的)分页,当然输出不是我需要的。我用这个来解决我的问题
router.get('/arrivalls', isAuthenticated, async (request, response, next) => {
jsonPreProcessor.response = response;
Arrival.aggregate(
[
// This is not working (may be it's not working in array)
// {
// "$sort": {
// "createdAt": 1
// }
// },
{
"$group": {
"_id": "$product",
"arrivals": {
"$push": "$$ROOT"
}
}
},
// {
// "$lookup": {
// "from": "arrivals",
// "localField": "product",
// "foreignField": "_id",
// "as": "product"
// }
// },
// {
// "$unwind": {
// "path": "$arrivals"
// }
// }
]
).then(arrivals => {
// console.log(arrivals);
return jsonPreProcessor.success(arrivals);
}).catch(error => {
return jsonPreProcessor.error(error.message);
});
});
输出应如下所示:
"data": {
"list": [
{
"_id": "5e1d5dba611485397cfb0386",
"arrivals": [
{
"_id": "5e1d5e26611485397cfb0387",
"quantity": 6,
"discount": 0,
"product": {
"_id": "5e1d5dba611485397cfb0386",
... // etc
},
"sellPrice": 5000,
"minSellPrice": 4500,
"createdAt": "2020-01-14T06:22:30.366Z",
"updatedAt": "2020-01-14T09:14:13.824Z",
"__v": 0
},
{
"_id": "5e1ff4d15d059430e8405f94",
"quantity": 2,
"discount": 0,
"product": {
"_id": "5e1d5dba611485397cfb0386",
... // etc
},
"sellPrice": 7000,
"minSellPrice": 6000,
"comment": "",
"createdAt": "2020-01-16T05:29:53.907Z",
"updatedAt": "2020-01-16T05:29:53.907Z",
"__v": 0
}
]
},
{
"_id": "5e1d84884d387d2334a7e9d9",
"arrivals": [
{
// etc...
}
]
}
],
"currentPage": 1,
"pages": 2,
"numberOfResults": 16,
"incompleteResults": true
},
"type": null
}我解决了我的问题。。这里是列表的分组、排序、填充和分页
const resPerPage = 10;
const page = request.query.page || 1;
Arrival.aggregate(
[
{
$lookup: {
from: 'products',
localField: 'product',
foreignField: '_id',
as: 'product'
}
},
{
$unwind: {
path: "$product",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'branchdans',
localField: 'branch',
foreignField: '_id',
as: 'branch'
}
},
{
$unwind: {
path: "$branch",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'colors',
localField: 'color',
foreignField: '_id',
as: 'color'
}
},
{
$unwind: {
path: "$color",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'types',
localField: 'product.type',
foreignField: '_id',
as: 'product.type'
}
},
{
$unwind: {
path: "$product.type",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'subcategories',
localField: 'product.subcategory',
foreignField: '_id',
as: 'product.subcategory'
}
},
{
$unwind: {
path: "$product.subcategory",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'categories',
localField: 'product.subcategory.category',
foreignField: '_id',
as: 'product.subcategory.category'
}
},
{
$unwind: {
path: "$product.subcategory.category",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'countries',
localField: 'product.country',
foreignField: '_id',
as: 'product.country'
}
},
{
$unwind: {
path: "$product.country",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'manufacturers',
localField: 'product.manufacturer',
foreignField: '_id',
as: 'product.manufacturer'
}
},
{
$unwind: {
path: "$product.manufacturer",
preserveNullAndEmptyArrays: true
}
},
{
$group: {
"_id": "$product._id",
"sizes": {
"$first": "$product.sizes"
},
"title": {
"$first": "$product.title"
},
"type": {
"$first": "$product.type"
},
"subcategory": {
"$first": "$product.subcategory"
},
"country": {
"$first": "$product.country"
},
"manufacturer": {
"$first": "$product.manufacturer"
},
"description": {
"$first": "$product.description"
},
"comment": {
"$first": "$product.comment"
},
"mode": {
"$first": "$product.mode"
},
"createdAt": {
"$first": "$product.createdAt"
},
"updatedAt": {
"$first": "$product.updatedAt"
},
"alt": {
"$first": "$product.alt"
},
arrivals: {
$push: "$$ROOT"
},
"date": {
$last: "$createdAt"
}
},
},
{
$unset: "arrivals.product"
},
{
$sort: {
"date": 1
}
},
{
$skip: (resPerPage * page) - resPerPage
},
{
$limit: resPerPage
}
]
).then(arrivals => {
Arrival.aggregate([
{
$group: {
"_id": "$product",
arrivals: {
$push: "$$ROOT"
},
"date": {
"$last": "$createdAt"
}
},
},
{
$sort: {
"date": 1
}
},
{
$count: "numberOfResults"
}
]).then(countArrivals => {
if(countArrivals.length === 0){
return jsonPreProcessor.error('Ошибка при высчитывании прибытий товаров');
}
// Todo make more practise
return jsonPreProcessor.paginate(arrivals, page, Math.ceil(countArrivals[0].numberOfResults / resPerPage), countArrivals[0].numberOfResults);
}).catch(error => {
return jsonPreProcessor.error(error.message);
});
// return jsonPreProcessor.success(arrivals);
}).catch(error => {
return jsonPreProcessor.error(error.message);
});