【问题标题】:How to hide _id from Aggregation?如何从聚合中隐藏_id?
【发布时间】:2023-03-06 12:28:02
【问题描述】:

我有这个查询:

produits = yield motor.Op(db.users.aggregate, [{"$unwind":"$pup"},{"$match":{"pup.spec.np":nomp}}, {"$group":{"_id":"$pup.spec.id","pup":{"$push":"$pup"}}}])

这给了我这个结果:

print produits

{u'ok': 1.0, u'result': [{u'_id': None, u'pup': [{u'avt': {u'fto': ..all the results}}]}]}

所以我可以这样做:

prod = produits["result"]

[{u'_id': None, u'pup': [{u'avt': {u'fto': ..all the results}}]}]

但是我怎样才能隐藏"_id",这样我只能得到:

[{u'pup': [{u'avt': {u'fto': ..all the results}}]}]

在普通查询中,我会简单地添加类似 {"_id":0} 的内容,但在这里它不起作用。

【问题讨论】:

    标签: mongodb pymongo motordriver tornado-motor


    【解决方案1】:

    来自 mongodb 文档

    您可以 $project 将结果排除在 _id 之外 - 这是您的意思吗?

    http://docs.mongodb.org/manual/reference/aggregation/#pipeline

    注意 _id 字段在默认情况下始终包含在内。您可以按如下方式明确排除 _id:

    db.article.aggregate(
        { $project : {
            _id : 0 ,
            title : 1 ,
            author : 1
        }}
    );
    

    以您为例,管道中的第一个操作是排除 _id 并包含其他属性。

    【讨论】:

    • 所以我必须添加 $project 运算符?
    • 加在最后会报错,怎么写[{"$unwind":"$pup"},{"$match":{"pup.spec.np":nomp}}, {"$group":{"_id":"$pup.spec.id","pup":{"$push":"$pup"}}}, {"$project":{"_id":0}}]
    • 查看您的命令,您的分组依据为空。我不熟悉语法,但如果您只是想从输出中消除 _id,请将{$project : {_id:0, pup:1}} 作为管道上的最后一个操作
    • 有效,放在最后:yield motor.Op(db.users.aggregate, [{"$unwind":"$pup"},{"$match":{"pup.spec.np":nomp}}, {"$group":{"_id":"$pup.spec.id","pup":{"$push":"$pup"}}}, {"$project" : {"_id":0, "pup":1}}])
    • 我们可以隐藏非id字段吗?
    【解决方案2】:

    Mongo 4.2 开始,$unset 聚合运算符可用作$project 的替代语法,用于仅删除字段:

    // { _id: "1sd", pup: [{ avt: { fto: "whatever"} }] }
    // { _id: "d3r", pup: [{ avt: { fto: "whatever else"} }] }
    db.collection.aggregate({ $unset: ["_id"] })
    // { pup: [{ avt: { fto: "whatever" } } ] }
    // { pup: [{ avt: { fto: "whatever else" } } ] }
    

    【讨论】:

      【解决方案3】:

      我对电机不熟悉,但你应该可以直接从结果字典中删除属性。

      >>> produits = {u'ok': 1.0, u'result': [{u'_id': None, u'pup': [{u'avt': {u'fto': 'whatever'}}]}]}
      >>> prod = produits['result'] 
      >>> del prod[0]['_id']
      >>> print prod
      [{u'pup': [{u'avt': {u'fto': 'whatever'}}]}]
      

      【讨论】:

      • 谢谢,是的,我可以使用 python 使用索引来做到这一点,但是当有多个结果时它会变得复杂,所以我必须迭代两次,用于结果(字典)和列表索引 BTW : motor 的工作方式与 pymongo 相同,只是它使用回调,因为它进行非阻塞调用
      【解决方案4】:

      这并不完全是 mongoWay 的做法,但您可以使用此工厂生成一个对象,该对象包含除 _id 之外的所有对象

      /**
       * Factory that returns a $project object that excludes the _id property https://docs.mongodb.com/v3.0/reference/operator/aggregation/project/ 
       * @params {String} variable list of properties to be included  
       * @return {Object} $project object including all the properties but _id
       */
      function includeFactory(/* properties */){
          var included = { "_id": 0 };
          Array.prototype.slice.call(arguments).forEach(function(include){
              included[include] = true
          })
      
          return { "$project": included }
      }
      

      然后像这样使用它:

      cities.aggregate(
      { "$group": { "_id": null, "max": { "$max": "$age" }, "min": { "$min": "$age" }, "average": { "$avg": "$age" }, "total": { "$sum": "$count" } } },
              includeFactory('max','min','average','total') 
      )
      

      【讨论】:

        猜你喜欢
        • 2019-03-12
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 1970-01-01
        • 2015-12-28
        • 1970-01-01
        • 1970-01-01
        • 2015-03-28
        相关资源
        最近更新 更多