ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

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

2019-11-11 22:56:12  阅读:385  来源: 互联网

标签:mongodb pymongo non-relational-database 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'

解决方法:

要删除最后一个条目,通常的想法(如您所提到的)是对数组进行迭代并获取其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" }
    ])

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

标签:mongodb,pymongo,non-relational-database,python
来源: https://codeday.me/bug/20191111/2022929.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有