问题描述
嗨,我正在为星级评定系统编写一些代码。
总体而言,我希望获得的是用户的总体平均星级得分和“星级条目”的平均星级。
“星级条目”可以由“ 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 (将#修改为@)