【问题标题】:Deleting Field using Pymongo使用 Pymongo 删除字段
【发布时间】:2020-12-23 09:22:41
【问题描述】:

我没有足够的声誉来发表评论,因此我不得不再次问这个问题。

我尝试了不同的方法来删除此处提到的动态更改的日期列,但对我没有任何效果:How to remove a field completely from a MongoDB document?

Environment_Details - 操作系统:Windows10,pymongo:3.10.1,MongoDB Compass App:4.4,python:3.6

我正在尝试删除“2020/08/24”列(在我的情况下,此日期将是动态的)。我的数据如下所示:

    [{
  "_id": {
    "$oid": "5f4e4dda1031d5b55a3adc70"
  },
  "Site": "ABCD",
  "2020/08/24": "1",
  "2020/08/25": "1.0"
},{
  "_id": {
    "$oid": "5f4e4dda1031d5b55a3adc71"
  },
  "Site": "EFGH",
  "2020/08/24": "1",
  "2020/08/25": "0.0"
}]

不会给我带来任何错误但也不会删除列/字段“2020/08/24”的命令:

col_name = "2020/08/24"
db.collection.update_many({}, {"$unset": {f"{col_name}":1}})
db.collection.update({}, {"$unset": {f"{col_name}":1}}, False, True)
db.collection.update_many({}, query =[{ '$unset': [col_name] }])

在尝试将 multi:True 与更新选项一起使用时,我总是遇到错误。

我使用的确切代码是:

    import pymongo
def connect_mongo(host, port, db):
    conn = pymongo.MongoClient(host, port)
    return conn[db]


def close_mongo(host, port):
    client = pymongo.MongoClient(host, port)
    client.close()


def delete_mongo_field(db, collection, col_name, host, port):
    """Delete column/field from a collection"""
    db = connect_mongo(host, port, db)
    db.collection.update_many({}, {"$unset": {f"{col_name}":1}})
    #db.collection.update_many({}, {'$unset': {f'{col_name}':''}})
    close_mongo(host,port)      

        
col_to_delete = "2020/08/30"
delete_mongo_field(mydb, mycollection, col_to_delete, 'localhost', 27017)

【问题讨论】:

    标签: python-3.x mongodb pymongo pymongo-3.x


    【解决方案1】:

    另外,您可能需要考虑更改数据模型以将日期存储为值而不是键,并考虑将它们存储为原生日期对象,例如

    import datetime
    import pytz
    
    db.testcollection.insert_many([
        {
            "Site": "ABCD",
            "Dates":  [
                {
                    "Date": datetime.datetime(2020, 8, 24, 0, 0, tzinfo=pytz.UTC),
                    "Value": "1"
                },
                {
                    "Date": datetime.datetime(2020, 8, 25, 0, 0, tzinfo=pytz.UTC),
                    "Value": "1.0"
                }]
        },
        {
            "Site": "EFGH",
            "Dates": [
                {
                    "Date": datetime.datetime(2020, 8, 24, 0, 0, tzinfo=pytz.UTC),
                    "Value": "1"
                },
                {
                    "Date": datetime.datetime(2020, 8, 25, 0, 0, tzinfo=pytz.UTC),
                    "Value": "0.1"
                }]
        }])
    

    但回到你的问题......第一个例子对我来说很好。你可以试试下面的示例代码,看看你是否得到不同的结果:

    from pymongo import MongoClient
    import pprint
    
    db = MongoClient()['testdatabase']
    
    db.testcollection.insert_many([{
        "Site": "ABCD",
        "2020/08/24": "1",
        "2020/08/25": "1.0"
    }, {
        "Site": "EFGH",
        "2020/08/24": "1",
        "2020/08/25": "0.0"
    }])
    pprint.pprint(list(db.testcollection.find({}, {'_id': 0})))
    
    col_name = "2020/08/24"
    db.testcollection.update_many({}, {"$unset": {f"{col_name}": 1}})
    
    pprint.pprint(list(db.testcollection.find({}, {'_id': 0})))
    

    结果:

    [{'2020/08/24': '1', '2020/08/25': '1.0', 'Site': 'ABCD'},
     {'2020/08/24': '1', '2020/08/25': '0.0', 'Site': 'EFGH'}]
    [{'2020/08/25': '1.0', 'Site': 'ABCD'}, {'2020/08/25': '0.0', 'Site': 'EFGH'}]
    

    【讨论】:

    • 谢谢..它就像一个魅力。从 delete_mongo_field 函数中删除 close_mongo 函数是否有特定原因?
    • 你不需要关闭连接,pymongo 会处理的。事实上,最好不要这样做,因为重新打开它们会增加大量开销。
    【解决方案2】:

    以下代码适用于 Python 3.8、PyMongo 3.11 和 MongoDB v 4.2.8。

    col_name = '2020/08/24'
    result = collection.update_many( { }, { '$unset': { col_name: '' } } )
    print(result.matched_count, result.modified_count)
    

    更新了帖子中的两个文档,并删除了名称为 "2020/08/24" 的字段。注意:MongoDB 集合的文档可以有一个带有/ 字符的字段名称(请参阅Documents - Field Names)。


    [编辑添加]

    以下delete_mongo_field 函数对我有效,通过删除提供的字段名称来正确更新文档:

    def delete_mongo_field(db, collection, col_name, host, port):
        db = connect_mongo(host, port, db)
        result = db[collection].update_many( { }, { '$unset': { col_name: 1 } } ) # you can also use '' instead of 1
        print(result.modified_count)
    

    【讨论】:

    • 我刚刚更新了这个问题,以提及我是如何通过创建函数来使用这些查询的。奇怪的是,如果我按照你们俩建议的方式使用它们,它可以工作,但如果我在函数中使用它们,什么也不会发生。你能建议我在这里缺少什么吗?
    • 我在您的代码中更正了答案。它对我有用。
    • 还要小心,您传递了一个字符串db 参数,然后将db 参数设置为一个pymongo 数据库对象。这在技术上并没有错,但如果你这样做,你会陷入一堆混乱。
    猜你喜欢
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 2014-11-09
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多