MST

星途 面试题库

面试题:MongoDB聚合管道结果写入集合:嵌套聚合与事务处理

现有两个集合,`users`集合包含用户信息(`userId`、`userName`等),`transactions`集合包含交易记录(`transactionId`、`userId`、`amount`、`transactionTime`)。要求通过聚合管道完成以下复杂操作:先找出每个用户最近一次交易记录,再根据这些最近交易记录计算每个用户交易金额的累计总和(考虑到同一用户可能有多条交易记录在不同时间),并且在将结果写入新集合`user_transaction_summary`的过程中,使用MongoDB的多文档事务确保数据一致性,写出完整的实现代码。
16.9万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

以下假设使用Python的PyMongo库来实现,并且已经连接到MongoDB数据库,client为MongoDB客户端对象:

from pymongo import MongoClient, ASCENDING, DESCENDING
from pymongo.errors import OperationFailure
import pymongo

# 连接MongoDB
client = MongoClient('mongodb://localhost:27017/')
db = client['your_database']
users = db['users']
transactions = db['transactions']
user_transaction_summary = db['user_transaction_summary']

try:
    with client.start_session() as session:
        session.start_transaction()
        # 找出每个用户最近一次交易记录
        recent_transactions = list(transactions.aggregate([
            {"$sort": {"userId": 1, "transactionTime": -1}},
            {"$group": {"_id": "$userId", "recentTransaction": {"$first": "$$ROOT"}}}
        ]))

        # 计算每个用户交易金额的累计总和
        user_summary = []
        for rt in recent_transactions:
            user_id = rt['_id']
            total_amount = sum(t['amount'] for t in transactions.find({"userId": user_id}))
            user_summary.append({
                "userId": user_id,
                "totalAmount": total_amount,
                "recentTransaction": rt['recentTransaction']
            })

        # 清空目标集合
        user_transaction_summary.delete_many({})
        # 将结果写入新集合
        user_transaction_summary.insert_many(user_summary, session=session)

        session.commit_transaction()
except OperationFailure as e:
    print(f"事务失败: {e}")
finally:
    client.close()

代码说明:

  1. 连接数据库:使用MongoClient连接到MongoDB数据库,并获取相应的集合对象。
  2. 事务处理:通过start_sessionstart_transaction开启事务,操作完成后通过commit_transaction提交事务,如果出现异常则捕获OperationFailure进行处理。
  3. 聚合操作
    • 首先通过$sortuserId升序和transactionTime降序排列,然后使用$group$first操作符找出每个用户最近一次交易记录。
    • 之后遍历最近交易记录,对每个用户在transactions集合中查询所有交易记录,计算交易金额的累计总和。
  4. 写入新集合:先清空user_transaction_summary集合,再将计算好的用户交易汇总信息插入到该集合中,确保数据一致性。

如果是使用其他编程语言与MongoDB交互,思路类似,但具体语法会有所不同。例如在Java中,事务处理和聚合操作的代码实现方式会有差异,但核心的数据库操作逻辑是一致的。