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

我想使用pymongo遍历Mongodb数据库Arraylist项目(事务列表)并删除特定于Arraylist的项目(事务列表)?

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

我如上所述使用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运算符,在其中您可以重新组织展平的文档,在此过程中,请使用组accumulator运算符来获取
通过使用应用于其嵌入式DATE字段的$max运算符的最后一个交易日期.

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

蒙哥壳

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

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

或者,您可以运行一个聚合操作,该操作也将使用$out管道更新集合,该管道将管道的结果写入同一集合:

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

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

蒙哥壳

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

尽管此方法可能比第一种方法更有效,但它首先需要了解现有领域,因此在某些情况下,该解决方案不切实际.

上一篇:pymongo无法与多线程一起使用


下一篇:python-如何更新mongodb集合