首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用按2个ids分组的聚合查询创建结构

使用按2个ids分组的聚合查询创建结构
EN

Stack Overflow用户
提问于 2022-05-31 11:30:02
回答 1查看 35关注 0票数 0

我有一个类似于下面所示的3个对象的各种文档的集合。

代码语言:javascript
复制
{
comment:{ 
      text_sentiment: "positive",
      topic: "A"
   }
}, // DOC-1

{
comment:{ 
      text_sentiment: "negative",
      topic: "A"
}}, // DOC-2

{
comment:{ 
      text_sentiment: "positive",
      topic: "B"
}},..//DOC-3 .. 

我想编写一个返回结果的聚合,其结构如下:

代码语言:javascript
复制
{
   topic: "A",
   topicOccurance: 2,
   sentiment: {
      positive: 3,
      negative: 2,
      neutral: 0
   }

},...

我已经编写了一个能够为topictext_sentiment分组的聚合,但我不知道如何创建类似于上面所示的结构。下面是我创建的聚合。

代码语言:javascript
复制
   db.MyCollection.aggregate({
       $match: {
           _id: "xyz",
           "comment.topic": {$exists: 1},
       }
   },{
       $group: {
           _id: {
               topic: "$comment.topic",
               text_sentiment: "$comment.text_sentiment"
               
           },
           total: {$sum: 1},
           
       }
   },{
       $project: {
           topic: {
               name: "$_id.topic",
               occurence: "$total"
           },
           sentiment: "$_id.text_sentiment"
       }
   },{
       $sort: {"topic.occurence": -1}
   })

它按topicsentiment分组,但结构与上面的结构不匹配。我怎样才能得到类似的结构?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-31 11:46:56

答案1

您需要2个$group阶段。

  1. $match
  2. $group -由comment.topiccomment.topic$sum组成。
  3. $group -由_id.topic$sum组成的集团,并添加text_sentimenttotal从前一阶段通过$pushtext_sentiments
  4. $project -装饰输出文件。设置sentiment,通过$arrayToObjecttext_sentiments数组转换为键值对.
  5. $sort
代码语言:javascript
复制
db.collection.aggregate([
  {
    $match: {
      _id: "xyz",
      "comment.topic": {
        $exists: 1
      },
      
    }
  },
  {
    $group: {
      _id: {
        topic: "$comment.topic",
        text_sentiment: "$comment.text_sentiment"
      },
      total: {
        $sum: 1
      },
      
    }
  },
  {
    $group: {
      _id: "$_id.topic",
      total: {
        $sum: 1
      },
      text_sentiments: {
        $push: {
          k: "$_id.text_sentiment",
          v: "$total"
        }
      }
    }
  },
  {
    $project: {
      topic: "$_id",
      topicOccurance: "$total",
      sentiment: {
        "$arrayToObject": "$text_sentiments"
      }
    }
  },
  {
    $sort: {
      "topicOccurance": -1
    }
  }
])

蒙戈游乐场样本(答案1)

答案2

正如前面提到的text_sentiment值是固定的,您可以使用下面的查询:

代码语言:javascript
复制
db.collection.aggregate([
  {
    $match: {
      _id: "xyz",
      "comment.topic": {
        $exists: 1
      },
      
    }
  },
  {
    $group: {
      _id: "$comment.topic",
      total: {
        $sum: 1
      },
      text_sentiments: {
        $push: "$comment.text_sentiment"
      }
    }
  },
  {
    $project: {
      topic: "$_id",
      topicOccurance: "$total",
      sentiment: {
        "positive": {
          $reduce: {
            input: "$text_sentiments",
            initialValue: 0,
            in: {
              $sum: [
                "$$value",
                {
                  "$cond": {
                    "if": {
                      $eq: [
                        "$$this",
                        "positive"
                      ]
                    },
                    "then": 1,
                    "else": 0
                  }
                }
              ]
            }
          }
        },
        "negative": {
          $reduce: {
            input: "$text_sentiments",
            initialValue: 0,
            in: {
              $sum: [
                "$$value",
                {
                  "$cond": {
                    "if": {
                      $eq: [
                        "$$this",
                        "negative"
                      ]
                    },
                    "then": 1,
                    "else": 0
                  }
                }
              ]
            }
          }
        },
        "neutral": {
          $reduce: {
            input: "$text_sentiments",
            initialValue: 0,
            in: {
              $sum: [
                "$$value",
                {
                  "$cond": {
                    "if": {
                      $eq: [
                        "$$this",
                        "neutral"
                      ]
                    },
                    "then": 1,
                    "else": 0
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  {
    $sort: {
      "topicOccurance": -1
    }
  }
])

缺点:当添加/删除text_sentiment值时,您必须修改查询。

蒙戈游乐场样本(答案2)

答案3

另一种类似于答案2的方法是使用$size$filter替换$reduce

代码语言:javascript
复制
db.collection.aggregate([
  {
    $match: {
      //_id: "xyz",
      "comment.topic": {
        $exists: 1
      },
      
    }
  },
  {
    $group: {
      _id: "$comment.topic",
      total: {
        $sum: 1
      },
      text_sentiments: {
        $push: "$comment.text_sentiment"
      }
    }
  },
  {
    $project: {
      topic: "$_id",
      topicOccurance: "$total",
      sentiment: {
        "positive": {
          $size: {
            $filter: {
              input: "$text_sentiments",
              cond: {
                $eq: [
                  "$$this",
                  "positive"
                ]
              }
            }
          }
        },
        "negative": {
          $size: {
            $filter: {
              input: "$text_sentiments",
              cond: {
                $eq: [
                  "$$this",
                  "negative"
                ]
              }
            }
          }
        },
        "neutral": {
          $size: {
            $filter: {
              input: "$text_sentiments",
              cond: {
                $eq: [
                  "$$this",
                  "neutral"
                ]
              }
            }
          }
        },
        
      }
    }
  },
  {
    $sort: {
      "topicOccurance": -1
    }
  }
])

蒙戈游乐场样本(答案3)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72447009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档