【问题标题】:Finding/Counting Duplicate Values in Array in MongoDB在 MongoDB 中的数组中查找/计算重复值
【发布时间】:2020-03-18 23:36:54
【问题描述】:

我是 mongo 数据库的新手。使用 Robo3t 软件
我必须根据 channel_id 找出数组中的重复值。
我做了一项研究,发现需要使用聚合来进行分组并找到相应的计数。
我开发了以下查询,但结果不如预期。

示例文档:

{
    "_id" : ObjectId("59b674d141b47e5401897d31"),
    "subscribed_channels" : [ 
        {
            "channel_id" : "1001",
            "channel_name" : "StarPlus",
            "channelPrice":"100"
        }, 
        {
            "channel_id" : "1002",
            "channel_name" : "StarGold",
            "channelPrice":"75"
        }, 
        {
            "channel_id" : "1001",
            "channel_name" : "StarPlus",
            "channelPrice":"100"
        },
        {
            "channel_id" : "1003",
            "channel_name" : "SetMax",
            "channelPrice":"80"
        }
    ],
    "viewer_account_id" : "59b6745b41b47e5401143b3d",
    "public_id_type" : "PHONE_NUMBER",
    "viewer_id" : "+919322264403",
    "role" : "CONSUMER",
    "active" : true,
    "date_time_created" : NumberLong(1505129681330),
    "date_time_modified" : NumberLong(1569320824387)
}

{
        "_id" : ObjectId("59b674d141b47e5401897d31"),
        "subscribed_channels" : [ 
            {
                "channel_id" : "1001",
                "channel_name" : "StarPlus",
                "channelPrice":"100"
            }, 
            {
                "channel_id" : "1002",
                "channel_name" : "StarGold",
                "channelPrice":"75"
            }, 
            {
                "channel_id" : "1001",
                "channel_name" : "StarPlus",
                "channelPrice":"100"
            },
             {
                "channel_id" : "1001",
                "channel_name" : "StarPlus",
                "channelPrice":"100"
            }
        ],
        "viewer_account_id" : "59b6745b41b47e5401143c56",
        "public_id_type" : "PHONE_NUMBER",
        "viewer_id" : "+919322264404",
        "role" : "CONSUMER",
        "active" : true,
        "date_time_created" : NumberLong(1505129681330),
        "date_time_modified" : NumberLong(1569320824387)
    }

以上只是文档查看者的 2 条记录

查询:

db.getCollection('viewers').aggregate([ 
        {
                    "$group" : 
                    {_id:{
                        //viewer_id:"$consumer_id",
                        enterprise_id:"$subscribed_channels.channel_id",
                         }, 
                         "viewer_id": {
                             $first: "$viewer_id"
                        },
                        count:{$sum:1}
                        }},

                        {
                          "$match": {"count": { "$gt": 1 }}
                        }
                 ]) 

实际输出:

{
    "_id" : {
        "enterprise_id" : [ 
            "1001", 
            "1001", 
            "1002",
            "1003"
        ]
    },
    "consumer_id" : "+919322264403",
    "count" : 2.0
}
{
    "_id" : {
        "enterprise_id" : [ 
            "1001", 
            "1002", 
            "1001",
            "1001
        ]
    },
    "consumer_id" : "+919322264404",
    "count" : 2.0
}

预期输出:

我想根据 subscribed_channels.channel_id 进行分组并分别获取计数

{
    "_id" : {
        "enterprise_id" : [ 
            "1001", 
            "1001", 
            "1002",
            "1003"
        ]
    },
    "consumer_id" : "+919322264403",
    "count" : 2.0
}
{
    "_id" : {
        "enterprise_id" : [ 
            "1001", 
            "1001", 
            "1001",
            "1002
        ]
    },
    "consumer_id" : "+919322264404",
    "count" : 3.0
}

没有根据 channel_id 进行分组,计数也不正确。
计数甚至没有给我订阅的频道 ID,也没有给出重复的频道 ID。

请指导我构建一个给出正确结果的查询。

【问题讨论】:

  • 因此,如果您想要重复第一个文档将有 1,而第二个文档将有 2,如果我没有错,那是正确的还是您给出的内容是正确的?因为第一个文档中的["1001", "1002", "1003"] 将是唯一的,唯一的重复是另一个1001.. 那么如果你有这个[ "1002", "1002", "1001", "1001" ],你认为它是4 个重复吗?
  • 嗨@whoami。谢谢你的回复。我想要根据文件的结果。第一个文档的计数为 2,因为有两个 1001,第二个文档的计数为 3,因为有三个 1001。另外,根据您的理解,如果我得到第一个给出 1 的文档和第二个给出 2 的文档,它会起作用。请让我知道是否需要任何其他澄清,我会更新我的问题
  • 嗨@whoami。我想突出显示包含基于 channel_id 重复的文档。你能给我一个开始的查询吗?
  • 我觉得计数为 1 代表第 1 次和 2 次代表第 2 次是完美的,这是正确的,因为这些是重复的元素数量(另外,如果您只需要具有重复项的文档,则不需要计数,这是您的实际问题吗?或者您是否想要所有文档和添加字段(某些字段,如 hasDups : true)用于那些有重复的文档?)
  • @whoami ,是的,谢谢您的建议。是的,你是正确的,因为第一个和第二个是 1 是完美的,并且会满足我的要求,因为我会知道哪些 channel_ids 在文档中重复。此外,添加字段也足够了,但 option1 看起来更突出。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

试试下面的查询:

查询:

db.collection.aggregate([
  /** project only needed fields & transform fields as you like */
  {
    $project: {
      customer_id: "$viewer_id",
      enterprise_id: "$subscribed_channels.channel_id",
      count: {
        /** Subtract size of original array & newly formed array which has unique values to get count of duplicates */
        $subtract: [
          {
            $size: "$subscribed_channels.channel_id" // get size of original array
          },
          {
            $size: {
              $setUnion: ["$subscribed_channels.channel_id", []] // This will give you an array with unique elements & get size of it
            }
          }
        ]
      }
    }
  }
]);

测试: MongoDB-Playground

【讨论】:

  • 嗨@whoami。执行上述查询给出错误错误:命令失败:{“ok”:0,“errmsg”:“$size 的参数必须是一个数组,但类型为:缺失”,“code”:17124,“codeName " : "Location17124" } : 聚合失败。我的文件损坏了吗?
  • @AjinkyaKarode :是的,我认为您的一些文档没有 subscribed_channels 作为数组。你能看看这是否正确?你想对那些做什么?
  • 嗨@whoami 抱歉,我刚刚验证了所有文档,是的,在某些文档中没有 subscribed_channel 字段,因为该查看者没有订阅。我该如何处理这样的文档?
  • @AjinkyaKarode:你要对那些文档做什么?你想从结果中删除那些吗?
  • 嗨@whoami。感谢您的所有努力,刚刚验证了输出。 mongoplayground.net/p/GxtKlE0fkst 我的计数超过 0。我会查看您推荐的网站,但如果我想向您学习,是否有可能?任何电子邮件 ID 或链接?
猜你喜欢
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多