如何使用pymongo迭代或删除MongoDb数组列表项?

2024-10-01 02:26:32 发布

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

我想使用pymongo迭代Mongodb数据库Arraylist项(事务列表)并删除Arraylist特定的(事务列表)项?在

enter image description here

我使用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'

Tags: noselfiddatetimedateattributescollectionint
1条回答
网友
1楼 · 发布于 2024-10-01 02:26:32

要删除最后一个条目,一般的想法(如您所述)是迭代数组并获取最后一个元素的索引(由其DATE字段表示),然后通过使用^{}删除它来更新集合。因此,这项工作所需的关键数据是DATE值和文档的{}。在

您可以采取的一种方法是首先使用聚合框架来获取这些数据。这样,您就可以运行一个管道,其中第一步是使用使用标准MongoDB查询的^{}操作符过滤集合中的文档。在

过滤文档后的下一步是展平TRANSACTION数组,即对列表中的文档进行非规范化处理,这样就可以过滤最后一个项目,即通过DATE字段获得最后一个文档。这可以通过^{}运算符实现,对于每个输入文档,输出n个文档,其中n是数组元素的数目,对于空数组可以是零。在

解构数组之后,为了得到最后一个文档,使用^{}运算符,在这里可以重新组合展开的文档,并在此过程中使用groupaccumulator运算符来获得 最后一个TRANSACTION日期,方法是使用应用于其嵌入的DATE字段的^{}运算符。在

因此,本质上,运行以下管道并使用结果来更新集合。例如,可以运行以下管道:

mongo外壳

db.block_chain.aggregate([
    { "$match": { "_id": coin_id } },
    { "$unwind": "$TRANSACTION" },
    { 
        "$group": {
            "_id": "$_id",
            "last_transaction_date": { "$max": "$TRANSACTION.DATE" }
        }
    }
])

然后,您可以使用^{}方法或聚合游标从该聚合操作中获取包含更新数据的文档,并更新您的集合:

^{pr2}$

python

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"] 
                } 
            } 
        }
    )

或者,也可以运行单个聚合操作,该操作还将使用^{}管道更新集合,该管道将管道的结果写入同一个集合:

If the collection specified by the $out operation already exists, then upon completion of the aggregation, the $out stage atomically replaces the existing collection with the new results collection. The $out operation does not change any indexes that existed on the previous collection. If the aggregation fails, the $out operation makes no changes to the pre-existing collection.

例如,可以运行以下管道:

mongo外壳

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" }
])

python

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" }
    ])

虽然这种方法可能比第一种方法更有效,但它首先需要了解现有领域,因此在某些情况下,解决方案不可行。在

相关问题 更多 >