Mongoose 聚合并获得点赞数

Posted

技术标签:

【中文标题】Mongoose 聚合并获得点赞数【英文标题】:Mongoose aggregate and get likes count 【发布时间】:2020-08-01 20:24:32 【问题描述】:

我有一个关于 Mongoose 聚合的查询。我一直在尝试分别获取用户详细信息以及喜欢和爱计数及其关系,但我无法成功。

这是我的场景,我有一个用户表和反应表。用户表保存用户详细信息,反应表包含用户详细信息以及喜欢用户的其他信息。在我的模式中,它是类型,例如:type='like' 或 love,所以我需要获取用户详细信息以及喜欢的数量。我是 MongoDB 新手。

这是我的代码:

用户架构

// Importing Node packages required for schema
const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const validateEmail = function(email) 
  const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w2,3)+$/;
  return re.test(email)
;
//= ===============================
// User Schema
//= ===============================
const UserSchema = new Schema(
  email: 
    type: String,
    trim: true,
    lowercase: true,
  ,
  reactions : [
     type: Schema.Types.ObjectId, ref: 'ProfileReaction' 
  ],
,
  
    timestamps: true
  
);


module.exports = mongoose.model('User', UserSchema);

反应模式

const mongoose = require('mongoose'),
  Schema = mongoose.Schema;

  const ProfileReactionSchema = new Schema(
    likedBy:  
      type: Schema.Types.ObjectId, 
      ref: 'User',
      required: true,
      index: true
    ,
    user:  
        type: Schema.Types.ObjectId, 
        ref: 'User',
        required: true,
        index: true
      ,
    type: 
      type: String,
      required: true,
    ,
  ,
    
      timestamps: true // Saves createdAt and updatedAt as dates. createdAt will be our timestamp.
    
);

  module.exports = mongoose.model('ProfileReaction', ProfileReactionSchema);

我真正想要的是下面的东西


   _id: '1234',
   email: 'xyz@gmail.com',
   reactions: [
      
         _id: '1235',
         likedBy: ...,
         user: ...,
         type: 'like'
      ,
      
         _id: '1236',
         likedBy: ...,
         user: ...,
         type: 'love'
      
   ],
   noOfLikes: 1,
   noOfLoves: 1

到目前为止,我尝试过的是,但这只是给了我关系,但我没有得到喜欢和爱的数量。但我需要他们都喜欢计数,喜欢计数和关系

const user = await User.findOne($or: [
    req.params.id.match(/^[0-9a-fA-F]24$/) ? _id: mongoose.Types.ObjectId(req.params.id)
    : uid: req.params.id
    ]).populate([
      
        path: 'reactions',
        model: 'ProfileReaction',
        populate: [
          
            path: 'likedBy',
            model: 'User'
          
        ]
      
    ]);

我正在使用版本mongoose v5.6.10

【问题讨论】:

快速提醒:您的问题无需添加“请帮助我”或其他乞求信息。读者知道你需要帮助,而旨在引起同情的悲痛呼喊可能会让读者觉得是强制性的。请记住,这里的帮助者大多是志愿者。同样,如果读者需要澄清,您无需邀请他们发表评论——当然,作为 17k 用户,您不会认为读者不知道网站的运作方式。请尽量坚持技术写作。 Stack Overflow 不是聊天室:-) 感谢您的输入和更正 【参考方案1】:

你可以在下面使用$lookup聚合

User.aggregate([
   "$match": 
    "$or": [
      req.params.id.match(/^[0-9a-fA-F]24$/)
        ?  "_id": mongoose.Types.ObjectId(req.params.id) 
        :  "uid": req.params.id 
    ]
  ,
   "$lookup": 
    "from": ProfileReaction.collection.name,
    "let":  "reactions": "$reactions" ,
    "pipeline": [
       "$match": 
        "$expr":  "$in": ["$_id", "$$reactions"] ,
        "type": "like"
      
    ],
    "as": "likeReactions"
  ,
   "$lookup": 
    "from": ProfileReaction.collection.name,
    "let":  "reactions": "$reactions" ,
    "pipeline": [
       "$match": 
        "$expr":  "$in": ["$_id", "$$reactions"] ,
        "type": "love"
      
    ],
    "as": "loveReactions"
  ,
   "$addFields": 
    "noOfLikes":  "$size": "$likeReactions" ,
    "noOfLoves":  "$size": "$loveReactions" 
  
])

【讨论】:

感谢您帮助解决我的问题。我在我的 OP 中遗漏了一些东西。请原谅我。实际上我的反应表包含不同类型的喜欢,例如:类型喜欢或爱。所以你能建议我如何分别获得喜欢计数和爱计数,我还需要它的关系,如反应,每个反应都包含用户,所以我需要在每个反应上填充用户关系。我怎样才能做到这一点?我已经更新了我的 OP 太棒了,这解决了我长期以来一直在苦苦挣扎的大部分问题。只有一个丢失的查询我还需要填充嵌套关系,但现在我只得到一个级别的关系。用户 > 反应,但我还想要的是每个反应的嵌套关系。每个反应都包含用户 ID,例如。喜欢的人或用户。请问我该如何填充这些

以上是关于Mongoose 聚合并获得点赞数的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 聚合获取计数并将新值附加到查询结果

Mongoose 查询最近 24 小时内获得点赞的文档

MongoDB 聚合与 Mongoose 虚拟

Mongoose:聚合获取数组类型字段的文档并根据特定字段过滤这些文档

Mongoose 聚合返回空结果并在 mongo 控制台中工作 [重复]

Mongoose 聚合返回空结果并在 mongo 控制台中工作 [重复]