微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我想使用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" }
    ])

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐