如何解决使用mongoose-aggregate-paginate-v2时,如何在子文档中汇总,填充,排序和获取带有数组的项目的平均值?
嗨,我正在为星级评定系统编写一些代码。
总体而言,我希望获得的是用户的总体平均星级得分和“星级条目”的平均星级。
“星级条目”可以由“ n”个星级定义组成(请参见下面的架构),并且应该具有这些定义的平均值,例如:
date: 10 Jan 2020
communication - 3 stars
attire - 3 stars
*average 3 stars*
date: 6 Jan 2020
communication - 2 stars
attire - 1 stars
*average 1.5 stars*
总体平均星级得分是通过将所有“星级”的平均值作为计算得出的:
10 Jan 2020 - 3 stars
6 Jan 2020 - 2 stars
*average 2.5 stars*
我还希望按日期对条目进行分页和排序(最后一位) 我不反对运行两个查询,一个查询获取“总平均数”和userId,第二个查询获取每个条目的“平均星星数”和分页信息。
UseStar架构
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongooseAggregatePaginate = require('mongoose-aggregate-paginate-v2');
const UserStarSchema = new Schema({
userId: { type: Schema.Types.ObjectId,required: true },userIdGiver: { type: Schema.Types.ObjectId,dateCreated: { type: Date,required: true,default: Date.now },starsArray: [
{
starDefinitionId: { type: Schema.Types.ObjectId,ref: 'stardefinitions' },stars: { type: Number,default: 0 },},],});
UserStarSchema.plugin(mongooseAggregatePaginate);
module.exports = UserStar = mongoose.model('userStars',UserStarSchema);
以下是UserStar模式的一组数据示例:
{
"_id": "5f4d2e4a72112b46a0beddfc","userId": "5f490bed6a04684204a4502e","userIdGiver": "5f48f9209b714c2caccf1b89","starsArray": [
{
"stars": "0.5","_id": "5f4d2e4a72112b46a0beddfd","starDefinitionId": "5f4d207ae93051293ce82cae"
},{
"stars": "5","_id": "5f4d2e4a72112b46a0beddfe","starDefinitionId": "5f4d2067e93051293ce82cad"
}
],"dateCreated": "1598893642758"
}
StarDefinition模式
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const StarDefinitionSchema = new Schema({
Category: { type: String,Definition: { type: String,});
module.exports = StarDefinition = mongoose.model('stardefinitions',StarDefinitionSchema);
以下是stardefinition模式的示例:
{
"_id": "5f4d2067e93051293ce82cad","Category": "Attire","Definition": "Were they dressed well?"
}
预期输出
请注意,starDefinitionId已填充了StarDefinition中的所有数据
{
"userId": "5f490bed6a04684204a4502e","average": 2.25,"docs": [
{
"_id": "5f4d33dfe5171d3de4e861ab","average": 2,"starsArray": [
{
"stars": 1,"_id": "5f4d33dfe5171d3de4e861ac","starDefinitionId": {
"_id": "5f4d207ae93051293ce82cae","Category": "Communication","Definition": "How well did they communicate?","__v": 0
}
},{
"stars": 3,"_id": "5f4d33dfe5171d3de4e861ad","starDefinitionId": {
"_id": "5f4d2067e93051293ce82cad","Definition": "Were they dressed well?","__v": 0
}
}
],"dateCreated": "2020-08-31T17:31:11.081Z","__v": 0,"stardefinitionsIndex": null
},{
"_id": "5f4d2f0f4d041239e4aa2a2c","average": 2.5,"starsArray": [
{
"stars": 3,"_id": "5f4d2f0f4d041239e4aa2a2d",{
"stars": 2,"_id": "5f4d2f0f4d041239e4aa2a2e","dateCreated": "2020-08-31T17:10:39.125Z","stardefinitionsIndex": null
}
],"totalDocs": 4,"limit": 2,"page": 1,"totalPages": 2,"pagingCounter": 1,"hasPrevPage": false,"hasNextPage": true,"prevPage": null,"nextPage": 2
}
这是我目前正在使用的:
版本1
var id = mongoose.Types.ObjectId(userId);
var agg_match = {
$match: { userId: id },};
var agg_lookup = {
$lookup: {
from: 'userStars',localField: 'starsArray.starDefinitionId',foreignField: '_id',as: 'stardefinitions',};
var agg_unwind = {
$unwind: {
path: '$stardefinitions',preserveNullAndEmptyArrays: true,includeArrayIndex: 'stardefinitionsIndex',};
var agg_sort = {
$sort: {
dateCreated: -1,};
var agg = [agg_match,agg_lookup,agg_unwind,agg_sort];
var pageAndLimit = {
page: page,limit: limit,};
var myAggregate = UserStar.aggregate(agg);
if (debugThis) {
console.log('aggregation ',JSON.stringify(agg));
console.log('page and limit',JSON.stringify(pageAndLimit));
}
var entry = await UserStar.aggregatePaginate(myAggregate,pageAndLimit);
我有分页和限制功能(使用mongoose-aggregate-paginate-v2)
输入
userId = "5f490bed6a04684204a4502e"
page = 0
limit = 2
第1版的输出-接近我想要的,但不完全是
{
"docs": [
{
"_id": "5f4d33dfe5171d3de4e861ab","starsArray": [
{
"stars": 5,"starDefinitionId": "5f4d207ae93051293ce82cae"
},{
"stars": 5,"starDefinitionId": "5f4d2067e93051293ce82cad"
}
],"starsArray": [
{
"stars": 4.5,{
"stars": 4.5,"nextPage": 2
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。