【问题标题】:Pymongo: Best way to remove $oid in ResponsePymongo:在响应中删除 $oid 的最佳方法
【发布时间】:2020-07-02 06:01:07
【问题描述】:

我最近开始使用 Pymongo,现在我想找到在 Response 中删除 $oid 的最佳方法

当我使用find时:

result = db.nodes.find_one({ "name": "Archer" }

并得到响应:

json.loads(dumps(result))

结果是:

{
  "_id": {
  "$oid": "5e7511c45cb29ef48b8cfcff"
  },
  "about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}

我的预期:

{
  "_id": "5e7511c45cb29ef48b8cfcff",
  "about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}

如您所见,我们可以使用:

resp = json.loads(dumps(result))
resp['id'] = resp['id']['$oid']

但我认为这不是最好的方法。希望大家有更好的解决方案。

【问题讨论】:

    标签: pymongo pymongo-3.x flask-pymongo


    【解决方案1】:
    import re
    
    def remove_oid(string):
        while True:
            pattern = re.compile('{\s*"\$oid":\s*(\"[a-z0-9]{1,}\")\s*}')
            match = re.search(pattern, string)
            if match:
                string = string.replace(match.group(0), match.group(1))
            else:
                return string
    
    string = json_dumps(mongo_query_result)
    string = remove_oid(string)
    

    【讨论】:

      【解决方案2】:

      我正在使用某种形式的自定义处理程序。我设法删除了 $oid 并将其替换为 id 字符串:

      # Custom Handler
      def my_handler(x):
          if isinstance(x, datetime.datetime):
              return x.isoformat()
          elif isinstance(x, bson.objectid.ObjectId):
              return str(x)
          else:
              raise TypeError(x)
      
      # parsing
      def parse_json(data):
          return json.loads(json.dumps(data, default=my_handler))
      
      result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
                                   {'$addFields': {"_id": '$_id'}},
                                   {'$project': {'_id': 0}}])
      data = parse_json(result)
      

      【讨论】:

        【解决方案3】:

        首先,响应中没有$oid。您看到的是 python 驱动程序将 _id 字段表示为 ObjectId 实例,然后 dumps() 方法将 ObjectId 字段表示为字符串格式。 $oid 位只是为了让您知道该字段是一个 ObjectId,如果您以后需要用于某些目的。

        答案的下一部分取决于您要达到的目标。几乎可以肯定,您可以使用结果对象来实现它,而无需将其转换为 JSON。

        如果你只是想完全摆脱它,你可以这样做:

        result = db.nodes.find_one({ "name": "Archer" }, {'_id': 0})
        print(result)
        

        给出:

        {"name": "Archer"}
        

        【讨论】:

        • 感谢 Belly 的指导。正是我不想像你说的那样摆脱_id 字段。我想找到将$oid 值映射到响应中的_id 字段的最佳方法。那么如何才能得到预期的结果呢?
        • 我会回到我的观点......你为什么要这样做?让它看起来漂亮?将它作为一点 JSON 而不是作为一个很好的结果对象准备好做任何你需要的事情有什么目的?
        • 我只是想让 json 对于前端团队看起来更漂亮。不知道好不好?
        • _ids 并不是最漂亮的东西。如果这是您的目标,那么您的原始方法与任何方法一样好......
        • 我知道了,也许我会摆脱_id,因为不必要。谢谢
        【解决方案4】:

        您可以利用聚合:

        result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
                                     {'$addFields': {"Id": '$_id.oid'}},
                                     {'$project': {'_id': 0}}])
        data = json.dumps(list(result))
        

        在这里,我用$addFields 添加了一个新字段Id,在其中我引入了oid 的值。然后我进行投影,消除结果的_id 字段。之后,当我得到一个光标时,我把它变成了一个列表。

        它可能不会像你希望的那样工作,但总体思路就在那里。

        【讨论】:

        • 当我使用你的代码时,id 字段完全消失:(
        • 如果你这样做会怎样:{'$addFields': {"Id": '$_id.$oid'}} ?
        • 也消失了,兄弟。请记住我使用的是Pymongo
        猜你喜欢
        • 2019-12-04
        • 1970-01-01
        • 1970-01-01
        • 2019-01-23
        • 2017-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        相关资源
        最近更新 更多