【问题标题】:how to group in mongoDB and return all fields in result如何在 mongoDB 中分组并返回结果中的所有字段
【发布时间】:2019-03-05 03:14:24
【问题描述】:

我在 mongoDB 中使用聚合方法进行分组,但是当我使用 $group 时,它返回我用来分组的唯一字段。我试过$project,但它也不起作用。我也尝试了$first,它成功了,但结果数据现在采用不同的格式。

我需要的响应格式如下:

{
    "_id" : ObjectId("5b814b2852d47e00514d6a09"),
    "tags" : [],
    "name" : "name here",
    "rating" : "123456789"
}

在我的 query.response 中添加 $group 后,_id 的值发生了变化。 (并且 $group 只使用 _id,如果我尝试任何其他关键字,它会引发累加器错误。请解释一下。)

{
    "_id" :"name here" //the value of _id changed to the name field which i used in $group condition
}

我必须删除名称字段中的重复项,而不更改任何结构和字段。我也在使用 nodeJS 和猫鼬,所以请提供适用的解决方案。

【问题讨论】:

  • 发布一些示例数据
  • 我只是想删除重复项。假设我收到 50 个文档,其中 20 个具有相同的名称字段,我只想要一次。 ( 例如 {{"name" : "name1","rating":"123456"},{"name" : "name2","rating":"123456.004"},{"name" : "name1","rating ":"12345614.23"}})。我不想要第 3 个文件,因为它与第 1 个文件同名并且是重复的。在这种情况下我该怎么办?
  • 使用$first聚合获取其他字段。
  • 问题是当我使用组时,id 的值发生了变化,我不想要那个。
  • 例如。 {{"_id":ObjectId("123asdf),"name" : "name1","rating":"123456"},{"_id":ObjectId("1234asd),"name" : "name2","rating ":"123456.004"},{"_id":ObjectId("12345as"),"name" : "name1","rating":"12345614.23"}} 使用组返回此响应-> {{"_id" : " name1"},{"_id" : "name2"}}。我需要与以前相同的响应,但没有重复。

标签: node.js mongodb mongoose aggregation-framework


【解决方案1】:

我想按groupById 字段对我的集合进行分组,并将其存储为键值对,键为groupById,值作为该组的所有项目。

db.col.aggregate([{$group :{_id :"$groupById",newfieldname:{$push:"$"}}}]).pretty()

这对我来说很好用..

【讨论】:

    【解决方案2】:

    user2683814 的解决方案对我有用,但在我的情况下,当我们替换 newRoot 对象时,我有一个计数器累加器,最后阶段缺少计数字段,所以我使用 $mergeObjects 运算符来取回我的计数字段。

    db.collection.aggregate([
     {
      $group: {
        _id: '$product',
        detail: { $first: '$$ROOT' },
        count: {
          $sum: 1,
        },
      },
    },
    {
      $replaceRoot: {
        newRoot: { $mergeObjects: [{ count: '$count' }, '$detail'] },
      },
    }])
    

    【讨论】:

      【解决方案3】:

      您可以使用以下聚合查询。

      $$ROOT 按每个名称保留整个文档,后跟 $replaceRoot 将文档提升到顶部。

      db.col.aggregate([
        {"$group":{"_id":"$name","doc":{"$first":"$$ROOT"}}},
        {"$replaceRoot":{"newRoot":"$doc"}}
      ])
      

      【讨论】:

      【解决方案4】:

      您可以使用此查询

      db.col.aggregate([
                              {"$group" : {"_id" : "$name","data" : {"$first" : "$$ROOT"}}},
                              {"$project" : {
                                  "tags" : "$data.tags",
                                  "name" : "$data.name",
                                  "rating" : "$data.rating",
                                  "_id" : "$data._id"
                                  }
                              }])
      

      【讨论】:

        【解决方案5】:

        当你在任何数据库上对数据进行分组时,意味着你想对必填字段进行累加操作,而其他不包含在累加操作中的字段将被分组使用

         db.collection.aggregate([{
         $group: {
           _id: { field1: "", field1: "" },
           acc: { $sum: 1 }
         }}]
        

        _id 对象中的此处将包含您要保存的所有其他字段。

        对于您的数据,您可以试试这个

        db.collection.aggregate([{
            $group: {
                _id: "$name",
                rating: { $first: "$rating" },
                tags: { $first: "$tag" },
                docid: { $first: "$_id" }
            }
        },
        {
            $project: {
                _id: "$docid",
                name: "$_id",
                rating: 1,
                tags: 1
            }
        }])
        

        【讨论】:

        • 我只是想删除重复项。假设我收到 50 个文档,其中 20 个具有相同的名称字段,我只想要一次。 ( 例如 {{"name" : "name1","rating":"123456"},{"name" : "name2","rating":"123456.004"},{"name" : "name1","rating ":"12345614.23"}})。我不想要第 3 个文件,因为它与第 1 个文件同名并且是重复的。在这种情况下我该怎么办?
        • 你对同一个名字有不同的评分,所以你想在组中获得哪一个,或者你想对一个名字进行所有评分?
        • 先到先得,等级不是那么重要,重要的是文档必须具有不同的名称字段值。
        • 现在我收到“字段'名称'必须是累加器对象”错误。如果我用_id替换名称,它可以工作,但它会改变_id值。 {"_id" : "name1","rating" : "0.001","tags" : null,"id" : ObjectId("5b814c9752d47e00514e9fcf")}.. _id 的值正在改变,我不想改变。 _id 的实际值在“id”字段中接收。
        • 哦,对不起,我错了,你是对的,你将使用 _id 作为名称,然后使用投影。我正在更新我的查询
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-08
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多