使用mongoose-aggregate-paginate-v2时,如何在子文档中汇总,填充,排序和获取带有数组的项目的平均值?

问题描述

嗨,我正在为星级评定系统编写一些代码

总体而言,我希望获得的是用户的总体平均星级得分和“星级条目”的平均星级。

big picture diagram

“星级条目”可以由“ 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 (将#修改为@)