如何使用python和pymongo制作二维结构(字典中的字典)以存储在MongoDB中?



我会经常得到下面的数据,

item_1 = { "ip" : "66.70.175.192", "domain" : null, "date_downloaded" : "2017:08:23 12:25:05", "scanned_date_with_port" : [ { "scanned_date" : "2017:08:22 04:00:03", "port" : 25 }, { "scanned_date" : "2017:08:22 04:00:03", "port" : 110 } ], "ports" : [ 25, 110 ] }

如何在以下结构中将数据保存到pymongo中:

{"ip_1" : {"port" : [scanned_date_1, scanned_date_2]}, {"port_2" : [scanned_date_1, scanned_date_2]  }, "domain_name" : ["domain"] }
{"ip_2" : {"port" : [scanned_date_1, scanned_date_2]}, {"port_2" : [scanned_date_1, scanned_date_2]  }, "domain_name" : ["domain"] }

每当新的IP出现时,如果已经存在需要附加,否则添加新的。如果端口已经在一个 Ip 中,则附加该端口scanned_date否则添加该端口并scanned_date。

我怎样才能有效地做到这一点?将有大量数据需要循环。

for item in all_items:

每个"项目"将具有上述item_1结构。

您可以做的是更改数据结构并统一处理新IP和数据库中已有IP的方式,您只需请求给定的IP和端口,即可获得结构,部分填充或空,并且您将始终将新数据附加到现有列表或空列表中。为此,您将像工厂一样。

使用 $push update 运算符追加到数组。下面是一个完整的示例:

client = MongoClient()
db = client.test
collection = db.collection
collection.delete_many({})
collection.insert_many([
{"_id": "ip_1", "port": [1, 2], "port_2": [1, 2], "domain_name": "domain"},
{"_id": "ip_2", "port": [1, 2], "port_2": [1, 2], "domain_name": "domain"},
])
# A new request comes in with address "ip_2", port "port_2", timestamp "3".
collection.update_one({
"_id": "ip_2",
}, {
"$push": {"port_2": 3}
})
import pprint
pprint.pprint(collection.find_one("ip_2"))

终于我明白了。

bulkop = self.coll_historical_data.initialize_ordered_bulk_op()
for rs in resultset:
ip = rs["ip"]
scanned_date_with_port = rs["scanned_date_with_port"]
domain = rs["domain"]
for data in scanned_date_with_port:
scanned_date = data["scanned_date"]
port = data["port"]
# insert if not found, else update
retval = bulkop.find({"ip" : ip}).upsert().update({"$push" : {str(port) : scanned_date }, "$addToSet" : {"domain" : domain}} )
retval = bulkop.execute()

最新更新