MST

星途 面试题库

面试题:MongoDB 复杂场景下的增删改查设计

考虑一个电商订单系统,订单集合存储订单信息,每个订单文档包含订单号、下单用户信息、商品列表(每个商品有商品 ID、数量、价格等子字段)、订单状态、支付时间等信息。要求实现一个功能:查询过去一周内,状态为'已支付'且包含特定商品 ID 的订单,并统计这些订单中该商品的总购买数量。同时,设计相关的索引以优化此查询性能,给出完整的查询语句和索引创建语句。
18.0万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

假设使用 MongoDB 数据库,以下为解决方案:

索引创建语句

db.orders.createIndex({
    orderStatus: 1,
    paymentTime: 1,
    "items.productId": 1
});

上述索引将按 orderStatus(订单状态)、paymentTime(支付时间)和 items.productId(商品 ID)进行索引,以加速查询。

查询语句

const today = new Date();
const lastWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);

db.orders.aggregate([
    {
        $match: {
            orderStatus: "已支付",
            paymentTime: { $gte: lastWeek },
            "items.productId": "特定商品ID"
        }
    },
    {
        $unwind: "$items"
    },
    {
        $match: {
            "items.productId": "特定商品ID"
        }
    },
    {
        $group: {
            _id: null,
            totalQuantity: { $sum: "$items.quantity" }
        }
    }
]);

以上聚合操作首先使用 $match 筛选出过去一周内状态为“已支付”且包含特定商品 ID 的订单,接着通过 $unwind 展开 items 数组,再次使用 $match 确保是特定商品 ID,最后通过 $group 统计该商品的总购买数量。

请注意,如果使用其他数据库,如 MySQL,解决方案将有所不同:

表结构假设

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_info VARCHAR(255),
    order_status VARCHAR(50),
    payment_time DATETIME
);

CREATE TABLE order_items (
    order_item_id INT PRIMARY KEY,
    order_id INT,
    product_id VARCHAR(50),
    quantity INT,
    price DECIMAL(10, 2),
    FOREIGN KEY (order_id) REFERENCES orders(order_id)
);

索引创建语句

CREATE INDEX idx_order_status_time_product 
ON orders (order_status, payment_time);

CREATE INDEX idx_product_id 
ON order_items (product_id);

查询语句

SELECT SUM(oi.quantity) AS total_quantity
FROM orders o
JOIN order_items oi ON o.order_id = oi.order_id
WHERE o.order_status = '已支付'
  AND o.payment_time >= CURDATE() - INTERVAL 7 DAY
  AND oi.product_id = '特定商品ID';

此 SQL 查询在 MySQL 中完成相同功能,通过 JOIN 关联 orders 表和 order_items 表,并按条件筛选统计商品总数量。