【问题标题】:MongoDB count distinct items in an arrayMongoDB计算数组中的不同项目
【发布时间】:2017-11-19 14:53:07
【问题描述】:

我的actors 集合包含一个名为acted_in 的文档数组字段。而不是像这样返回acted_in.idmovies 的大小:{$size: $acted_in.idmovies},我想返回$acted_in.idmovies 中不同值的数量。我该怎么做?

c1 = actors.aggregate([{"$match": {'$and': [{'fname': f_name},
                                            {'lname': l_name}]}},
                       {"$project": {'first_name': '$fname',
                                     'last_name': '$lname',
                                     'gender': '$gender',
                                     'distinct_movies_played_in': {'$size': '$acted_in.idmovies'}}}])

【问题讨论】:

  • 您可以将$setDifference[] 一起使用,这将删除重复项。类似distinct_movies_played_in': {'$size': { $setDifference: [ '$acted_in.idmovies', []] }}

标签: python mongodb pymongo


【解决方案1】:

您基本上需要在其中包含$setDifference 以获得“不同”项目。所有“集合”在设计上都是“不同的”,通过获得从当前数组到空数组的“差异”[],您可以获得所需的结果。然后你可以申请$size

您也有一些常见的错误/误解。首先,当使用 $match 或任何 MongoDB 查询表达式时,您不需要使用 $and,除非有明确的情况需要这样做。 所有查询表达式参数都是“已经” AND 条件,除非另有明确说明,如 $or。所以不要明确地用于这种情况。

其次,您的$project 对每个字段都使用了显式字段路径变量。您不需要这样做只是为了返回该字段,并且在“表达式”中使用之外,您可以简单地使用 1 来表示您希望包含它:

c1  = actors.aggregate([
 { "$match": { "fname"': f_name, "lname": l_name } },
 { "$project": {
   "first_name": 1,
   "last_name": 1,
   "gender": 1,
   "distinct_movies_played_in": { 
     "$size": { "$setDifference": [ "$acted_in.idmovies", [] ] }
   } 
  }}
])

事实上,如果您实际使用的是支持 $addFields 的 MongoDB 3.4 或更高版本(并且数组中元素的符号 "$acted_in.idmovies" 表示您至少有 MongoDB 3.2),那么使用它而不是指定所有文档中的其他字段。

c1  = actors.aggregate([
 { "$match": { "fname"': f_name, "lname": l_name } },
 { "$addFields": {
   "distinct_movies_played_in": { 
     "$size": { "$setDifference": [ "$acted_in.idmovies", [] ] }
   } 
  }}
])

除非您明确需要指定“一些”其他字段。

这里的基本情况是不要使用$unwind 进行数组操作,除非您特别需要使用_id 键指向来执行$group 操作在从数组“内部”获得的值处。

在所有其他情况下,MongoDB 拥有比$unwind 更高效的数组操作符。

【讨论】:

  • 关于$unwind 操作符低效的有用见解。你的解决方案确实比我的更有效!
  • 感谢您:$countDistinct = $size: { $setDifference: ['$myArray', []] }
【解决方案2】:

这应该会给你你想要的:

actors.aggregate([
    {
        $match: {fname: f_name, lname: l_name}
    }, 
    {
        $unwind: '$tags'
    }, 
    {
        $group: {
                    _id: '$_id', 
                    first_name: {$first: '$fname'}, 
                    last_name: {$last: '$lname'}, 
                    gender: {$first: '$gender'}, 
                    tags: {$addToSet: '$tags'}
                }
    }, 
    {
        $project: {
                      first_name: 1, 
                      last_name: 1, 
                      gender: 1, 
                      distinct: {$size: '$tags'}
                  }
    }
])

tags数组解构后放回自己的一个集合中,那么你只需要得到那个集合的项数或者长度即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多