MongoDB 数据建模动态一对多关系

问题描述

我为一个板球(是的,运动)应用程序建模了数据,其中有两个集合有问题:会话和交付。会话是具有一些附加元数据(如位置、名称等)的交付集合。会话的元数据在创建后很少更改,但交付将始终在创建后更新几次(存储 ballTrack json,作为投球手的用户) ,以及作为击球手的用户)。我目前将数据建模为会话和交付是两个单独的集合,其中会话由每个交付对象内的 id 引用:

session: {   
    _id: ...,name: ...,thumbnailUrl: ...,deliveryCount: ...,team: teamId
}

delivery: {
    _id: ...,session: sessionId,bowler: userId,batsman: userId,ballTrack: {some json},calibration: {some json},team: teamId,...
}

此应用程序最重要的查询是聚合用户在其主页上参与的所有会话。识别用户是否在会话中的方法是检查他们是否是该会话中交付的投球手或击球手,或者他们是否是创建该会话的团队的团队成员。目前我正在对交付集合进行聚合,如下所示:

const matchCriteria: Array<Record<string,unkNown>> = [
        { bowler: userId },{ batsman: userId },];

    // match on all user's teams if all sessions specified
    if (all) {
        const userTeams: Array<TeamDocument['id']> = user.teams;
        matchCriteria.push({ team: { $in: userTeams } });
    }
await DeliveryModel.aggregate().match({
            $or: matchCriteria,deleted: false,})
        .group({
            _id: '$session',session: { $first: '$$ROOT.session' },})
        .lookup({
            from: 'sessions',localField: 'session',foreignField: '_id',as: 'session',}) ... (some additional projections and sorting)

这目前工作正常,但由于这是最重要的查询,我想考虑优化 $lookup,因为我不想随着集合的增长而产生性能成本。授予查找是在索引字段上,但我想知道是否将所有信息保存在一个集合中可能是要走的路。例如,我正在考虑两种替代模式。其中交付是会话中的一个子文档数组:

session: {   
   _id: ...,team: teamId
   deliveries: [{_id: ...,...
                }

这会将旧的聚合查询变成一个简单的查找查询,但我担心使用这种嵌套方法会使文档变大。每个会话的交付数量有上限(500 次交付/会话,交付文档大小约为 1kb)所以我不会达到 mongoDB bson 上限,但似乎仍然是不必要的开销来存储所有这些交付数据当我只需要此特定查询的会话信息时的会话(在您深入到特定会话之前不会显示交付数据)。

另一种方法是在每次交付中嵌套一些会话数据。这看起来像:


delivery: {
    _id: ...,session: {_id: sessionId,deliveryCount: ...}
    bowler: userId,...
}

这会在每个文档中保留所有必要的信息,但会在每个文档中复制会话数据(也不确定我将如何处理使用这种方法更新会话的 deliveryCount 字段)。

我知道这是很多,但希望得到一些关于更可取的架构设计的建议,或者我的当前是否可以很好地扩展。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)