Pymongo聚合:按字段数过滤(动态)

时间:2017-05-10 16:35:33

标签: python mongodb pymongo

让我们说我有一个聚合管道,现在导致一个集合,其中包含如下构建的文档:

{'name': 'Paul',
 'football_position': 'Keeper',
 'basketball_position': 4,...}

显然不是每个人都参加各种运动,所以对于某些文件来说,会有不存在的领域。关于他们的文件将是

{'name': 'Louis'}

我想要做的是在我的聚合管道中过滤至少参与一项运动的人

我知道使用{'$match': {'football_position': {'$exists': True}}}检查一个字段很容易,但我想检查是否存在这些字段。

我发现了一个有点相似的旧问题(Check for existence of multiple fields in MongoDB document),但它检查是否存在所有字段 - 虽然很麻烦,但可以通过乘法倍数{{}来实现1}}操作。另外,也许mongoDB现在有一种比编写自定义JavaScript函数更好的方法来处理它。

1 个答案:

答案 0 :(得分:1)

  

也许mongoDB现在有更好的方法来处理这个

是的,您现在可以使用聚合运算符$objectToArraySERVER-23310)将键转换为值。它应该能够计算动态'字段数量。将此运算符与$addFields组合可能非常有用。

两个运营商都可以在MongoDB v3.4.4 +中使用 以上面的文档为例:

db.sports.aggregate([
          { $addFields : 
             { "numFields" : 
               { $size:
                 { $objectToArray:"$$ROOT"}
               }
             }
          }, 
          { $match: 
            { numFields: 
              {$gt:2}
            }
          }
])

上面的聚合管道,首先会添加一个名为numFields的字段。该值将是数组的大小。该数组将包含文档中的字段数。第二阶段仅过滤2个字段和更多字段(两个字段,因为还有_id字段加name)。

PyMongo中,上述聚合管道如下所示:

cursor = collection.aggregate([
                         {"$addFields":{"numFields":
                                         {"$size":{"$objectToArray":"$$ROOT"}}}}, 
                         {"$match":{"numFields":{"$gt":2}}}
         ])

说完上述内容后,如果可能的话,我建议您重新考虑data models以便于访问。即,在插入/添加新的运动位置时添加新的字段以跟踪运动的数量。