MongoDB 对数组中的不同项进行计数

dim*_*s93 2 python mongodb pymongo

我的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'}}}])
Run Code Online (Sandbox Code Playgroud)

Nei*_*unn 7

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

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

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

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", [] ] }
   } 
  }}
])
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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