javascript – Mongoose / Mongodb基本trello喜欢在vue中渲染的方案问题

我正在创建一个非常基本的功能看板.

到目前为止,我的主板有4个型号:

用户模型

var userSchema = new Schema({
  name: {
    type: String,
    required: true
  }
})

module.exports = mongoose.model('User', userSchema)

板模型

var boardSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  lists: [ listSchema ]
  members: [
    {
      type: Schema.Types.ObjectId,
      ref: 'user'
    }
  ]
});

module.exports = mongoose.model('Board', boardSchema)

列表架构

let listSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  userCreated: {
    type: Schema.Types.ObjectId,
    required: true,
    ref: 'user'
  },
  boardId: {
    type: Schema.Types.ObjectId,
    required: true,
    ref: 'board'
  },
  sort: {
    type: Number,
    decimal: true,
    required: true
  }
})

module.exports = mongoose.model('List', listSchema)

卡架构

var cardSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  description: {
    type: String
  },
  boardId: {
    type: Schema.Types.ObjectId,
    required: true,
    ref: 'board'
  },
  listId: {
    type: Schema.Types.ObjectId,
    required: true,
    ref: 'list'
  },
  members: [
    {
      type: Schema.Types.ObjectId,
      ref: 'user'
    }
  ],
  sort: {
    type: Number,
    decimal: true,
    required: true
  }
})

module.exports = mongoose.model('Card', cardSchema)

我在找什么?

我的前端是用Vue.js和sortable.js拖放lib.

我想找到使用列表(列)和卡片来渲染电路板的最佳方法.

根据我的理解,我应首先通过成员数组中的用户ID获取我的主板.

然后我的主板已经嵌入了列表.

在第二次api请求中,我通过boardId获得所有卡片.

我的问题是 – 如何正确地将所有卡片放入/渲染到每个拥有者列表中?

所以最后我希望得到类似的东西:

{
  title: 'My board',
  lists: [
    {
      title: 'My list',
      _id: '35jj3j532jj'
      cards: [
       {
        title: 'my card',
        listId: '35jj3j532jj'
       }
      ]
    },
    {
      title: 'My list 2',
      _id: '4gfdg5454dfg'
      cards: [
       {
        title: 'my card 22',
        listId: '4gfdg5454dfg'
       },
       {
        title: 'my card 22',
        listId: '4gfdg5454dfg'
       }
      ]
    }
  ]
  members: [
    'df76g7gh7gf86889gf989fdg'
  ]
}

我试过了什么?

到目前为止,我只提出了一件事,那就是:

>两个api调用挂钩 – 一个用于获取带有列表的电路板,第二个用于获取所有卡.
>然后我循环通过列表和循环槽卡并通过ID将每张卡推入列表?

但是这种方式似乎我的列表需要有一个名为cards的空数组:[]仅用于按ID进行的前端卡到列表排序,似乎有些错误.

这是一个好方法吗?或者我应该重新设计我的模型和模式,并采取其他方式?任何帮助,将不胜感激!

最佳答案 您定义的模式非常好,但只进行了一次修改.

无需在Board模型中使用“列表”,因为它已经在列表中可用,并且如果将其保留在板中,则每次添加新列表时,您还需要编辑板.

这是流程的方式.

最初,当用户登录时,您需要向他们显示电路板列表.这应该很简单,因为您只需使用board集合上的user_id进行查找查询.

Board.find({members: user_id}) // where user_id is the ID of the user

现在,当用户点击特定的电路板时,您可以使用board_id获取列表,类似于上面的查询.

List.find({boardId: board_id}) // where board_id is the ID of the board

同样,您可以在list_id和board_id的帮助下获得卡片.

Card.find({boardId: board_id, listId: list_id}) // where board_id is the ID of the board and listId is the Id of the list

现在,让我们看一下您可能需要同时收集来自2个或更多集合的数据的情况.例如,当用户点击时,您不仅需要电路板中的列表,还需要该电路板中的卡.在这种情况下,您需要编写一个聚合,

        Board.aggregate([
        // get boards which match a particular user_id
        {
            $match: {members: user_id}
        },
        // get lists that match the board_id
        {
            $lookup:
            {
                from: 'list',
                localField: '_id',
                foreignField: 'boardId',
                as: 'lists'
            }
        }
    ])

这将返回电路板,在每个电路板中,将有一系列与该电路板相关的列表.如果某个特定的电路板没有列表,那么它将有一个空数组.

同样,如果要将卡添加到列表和电路板,聚合查询将更复杂,因此,

        Board.aggregate([
        // get boards which match a particular user_id
        {
            $match: {members: user_id}
        },
        // get lists that match the board_id
        {
            $lookup:
            {
                from: 'list',
                localField: '_id',
                foreignField: 'boardId',
                as: 'lists'
            }
        },
        // get cards that match the board_id
        {
            $lookup:
            {
                from: 'card',
                localField: '_id',
                foreignField: 'boardId',
                as: 'cards'
            }
        }
    ])

这将添加一系列卡片以及混合.同样,您也可以获得列表卡.

点赞