[英]How Iterate or remove MongoDb array list item using pymongo?
我想迭代Mongodb數據庫Arraylist項目(TRANSACTION列表)並使用pymongo刪除Arraylist特定(TRANSACTION List)項目?
我使用python pymongo創建如上所述的Mongo集合。 我想使用pymongo迭代數組列表項並僅在Arraylist中刪除最終項目?
使用Python pymongo進行數據插入查詢
# added new method create block chain_structure
def addCoinWiseTransaction(self, senz, coin, format_date):
self.collection = self.db.block_chain
coinValexists = self.collection.find({"_id": str(coin)}).count()
print('coin exists : ', coinValexists)
if (coinValexists > 0):
print('coin hash exists')
newTransaction = {"$push": {"TRANSACTION": {"SENDER": senz.attributes["#SENDER"],
"RECIVER": senz.attributes["#RECIVER"],
"T_NO_COIN": int(1),
"DATE": datetime.datetime.utcnow()
}}}
self.collection.update({"_id": str(coin)}, newTransaction)
else:
flag = senz.attributes["#f"];
print flag
if (flag == "ccb"):
print('new coin mined othir minner')
root = {"_id": str(coin)
, "S_ID": int(senz.attributes["#S_ID"]), "S_PARA": senz.attributes["#S_PARA"],
"FORMAT_DATE": format_date,
"NO_COIN": int(1),
"TRANSACTION": [{"MINER": senz.attributes["#M_S_ID"],
"RECIVER": senz.attributes["#RECIVER"],
"T_NO_COIN": int(1),
"DATE": datetime.datetime.utcnow()
}
]
}
self.collection.insert(root)
else:
print('new coin mined')
root = {"_id": str(coin)
, "S_ID": int(senz.attributes["#S_ID"]), "S_PARA": senz.attributes["#S_PARA"],
"FORMAT_DATE": format_date,
"NO_COIN": int(1),
"TRANSACTION": [{"MINER": "M_1",
"RECIVER": senz.sender,
"T_NO_COIN": int(1),
"DATE": datetime.datetime.utcnow()
}
]
}
self.collection.insert(root)
return 'DONE'
要刪除最后一個條目,一般的想法(如您所述)是迭代數組並獲取最后一個元素的索引,如其DATE
字段所示,然后通過使用$pull
刪除它來更新集合。 因此,您需要使用的關鍵數據是DATE
值和文檔的_id
。
您可以采取的一種方法是首先使用聚合框架來獲取此數據。 有了這個,您可以運行一個管道,其中第一步是使用使用標准MongoDB查詢的$match
運算符過濾集合中的文檔。
過濾文檔后的下一個階段是展平TRANSACTION
數組,即對列表中的文檔進行非規范化處理,以便您可以過濾最終項目,即通過DATE
字段獲取最后一個文檔。 這可以通過$unwind
運算符實現,該運算符為每個輸入文檔輸出n個文檔,其中n是數組元素的數量,對於空數組可以為零。
在解構數組之后,為了獲取最后一個文檔,使用$group
運算符,您可以在其中重新組合展平的文檔,並在此過程中使用組累加器運算符通過使用應用於其嵌入的$max
運算符來獲取最后的TRANSACTION
日期DATE
字段。
因此,實質上,運行以下管道並使用結果更新集合。 例如,您可以運行以下管道:
蒙戈貝殼
db.block_chain.aggregate([
{ "$match": { "_id": coin_id } },
{ "$unwind": "$TRANSACTION" },
{
"$group": {
"_id": "$_id",
"last_transaction_date": { "$max": "$TRANSACTION.DATE" }
}
}
])
然后,您可以使用toArray()
方法或聚合游標從此聚合操作獲取包含更新數據的文檔,並更新您的集合:
var docs = db.block_chain.aggregate([
{ "$match": { "_id": coin_id } },
{ "$unwind": "$TRANSACTION" },
{
"$group": {
"_id": "$_id",
"LAST_TRANSACTION_DATE": { "$max": "$TRANSACTION.DATE" }
}
}
]).toArray()
db.block_chain.updateOne(
{ "_id": docs[0]._id },
{
"$pull": {
"TRANSACTION": {
"DATE": docs[0]["LAST_TRANSACTION_DATE"]
}
}
}
)
蟒蛇
def remove_last_transaction(self, coin):
self.collection = self.db.block_chain
pipe = [
{ "$match": { "_id": str(coin) } },
{ "$unwind": "$TRANSACTION" },
{
"$group": {
"_id": "$_id",
"last_transaction_date": { "$max": "$TRANSACTION.DATE" }
}
}
]
# run aggregate pipeline
cursor = self.collection.aggregate(pipeline=pipe)
docs = list(cursor)
# run update
self.collection.update_one(
{ "_id": docs[0]["_id"] },
{
"$pull": {
"TRANSACTION": {
"DATE": docs[0]["LAST_TRANSACTION_DATE"]
}
}
}
)
或者,您可以運行單個聚合操作,該操作也將使用$out
管道更新您的集合,該管道將管道的結果寫入同一集合:
如果
$out
操作指定的集合已經存在,那么在聚合完成后,$out
階段將使用新結果集合原子地替換現有集合。$out
操作不會更改先前集合中存在的任何索引。 如果聚合失敗,$out
操作不會對預先存在的集合進行任何更改。
例如,您可以運行此管道:
蒙戈貝殼
db.block_chain.aggregate([
{ "$match": { "_id": coin_id } },
{ "$unwind": "$TRANSACTION" },
{ "$sort": { "TRANSACTION.DATE": 1 } }
{
"$group": {
"_id": "$_id",
"LAST_TRANSACTION": { "$last": "$TRANSACTION" },
"FORMAT_DATE": { "$first": "$FORMAT_DATE" },
"NO_COIN": { "$first": "$NO_COIN" },
"S_ID": { "$first": "$S_ID" },
"S_PARA": { "$first": "$S_PARA" },
"TRANSACTION": { "$push": "$TRANSACTION" }
}
},
{
"$project": {
"FORMAT_DATE": 1,
"NO_COIN": 1,
"S_ID": 1,
"S_PARA": 1,
"TRANSACTION": {
"$setDifference": ["$TRANSACTION", ["$LAST_TRANSACTION"]]
}
}
},
{ "$out": "block_chain" }
])
蟒蛇
def remove_last_transaction(self, coin):
self.db.block_chain.aggregate([
{ "$match": { "_id": str(coin) } },
{ "$unwind": "$TRANSACTION" },
{ "$sort": { "TRANSACTION.DATE": 1 } },
{
"$group": {
"_id": "$_id",
"LAST_TRANSACTION": { "$last": "$TRANSACTION" },
"FORMAT_DATE": { "$first": "$FORMAT_DATE" },
"NO_COIN": { "$first": "$NO_COIN" },
"S_ID": { "$first": "$S_ID" },
"S_PARA": { "$first": "$S_PARA" },
"TRANSACTION": { "$push": "$TRANSACTION" }
}
},
{
"$project": {
"FORMAT_DATE": 1,
"NO_COIN": 1,
"S_ID": 1,
"S_PARA": 1,
"TRANSACTION": {
"$setDifference": ["$TRANSACTION", ["$LAST_TRANSACTION"]]
}
}
},
{ "$out": "block_chain" }
])
雖然這種方法比第一種方法更有效,但它首先需要了解現有領域,因此在某些情況下解決方案不可行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.