如何取消设置除某些已知字段外的所有字段?

2024-05-23 16:18:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要删除文档的某些字段,但我只知道要保留的字段。如何取消设置除已知字段外的所有字段。例如:

数据库中的文档如下所示

{ 
  "_id" : ObjectId("1234567891234"),
  "name" : "testname",
  "settings" : {
    "pairing" : true}
  "subject" : "alarm"
}

我想删除“设置”和“主题”字段。所以会像下面这样。在

^{pr2}$

但是我不能只对字段使用“$unset”,因为我只知道要保留的字段。在

在pymongo有办法做到这一点吗。我发现了一个相关的问题,但我不知道在Python2.7中这是否可能。在

相关问题: How do I unset all fields except a known set of fields?


Tags: name文档id数据库truefields主题settings
2条回答

是的,有可能!如果要取消设置集合中多个文档的已知字段之外的所有字段,则最好的方法是使用“bulk”操作。在

mongodb3.2不推荐使用^{}及其关联方法。所以如果你应该使用^{}。在

from itertools import zip_longest # or izip_longest in Python 2.x
from pymongo import MongoClient, UpdateOne


client = MongoClient()
db = client.db
collection = db.collection
requests = []
fields = ['name', '_id']
for document in collection.find():
    unset_op = dict(zip_longest(set(document.keys()).difference(fields), [''], fill_value='')) 
    requests.append(UpdateOne({'_id': document['_id']}, {'$unset': unset_op}))
    # Execute per 1000 operations and re-init.
    if len(requests) == 1000:
        collection.bulk_write(requests)
        requests = []

# clean up the queues
if requests:
    collection.bulk_write(requests)

对于单个文档,您需要使用^{}方法,该方法返回与您的条件匹配的文档,然后^{}在3.0版本中新增

^{pr2}$

如果不使用最新版本的MongoDB或Pymongo驱动程序,则需要使用Bulk()API。在

bulk = collection.initialize_unordered_bulk_op()
count = 0
for document in collection.find():
    unset_op = dict(zip_longest(set(document.keys()).difference(fields), [''], fill_value=''))
    bulk.find({'_id': document['_id']}).update_one({'$unset': unset_op})
    count = count + 1
    if count % 1000 == 0:
        bulk.execute()
        bulk = collection.initialize_unordered_bulk_op()        
    if count > 0:
        bulk.execute()

对于单个文档,您可以依赖^{}方法。在

unset_op = dict(izip_longest(set(document.keys()).difference(fields), [''], fill_value=''))
collection.update_one({'_id': document['_id']}, {'$unset': unset_op})

一种可能的方法是在不使用“$set”的情况下更新整个文档,删除未指定的字段,例如:

{ 
  "_id" : ObjectId("1234567891234"),
  "name" : "testname",
  "settings" : {
    "pairing" : true}
  "subject" : "alarm"
}

^{pr2}$

将导致删除其他字段,但“name”。 因此,在python中可以执行以下操作:

result = db.collection_name.find_one({"name":"testname"})

(如果您知道可以搜索的ID,但一定要导入from bson.objectid import ObjectId)。之后,将集合存储在result中。然后,您需要使用已知的记录更新示例:

db.collection_name.update_one({"_id":result["_id"]},{"name":result["name"]})

这是一种方法。当然,它只保留“name”和“\u id”,但所有其他未指定的字段都将被删除。希望有帮助

相关问题 更多 >