【问题标题】:Mongoose Schema - How to add an order attribute for sortingMongoose Schema - 如何添加排序属性
【发布时间】:2020-07-04 22:24:12
【问题描述】:

我目前正在构建一个 Web 应用程序,您可以在其中创建带有歌词 objectId 数组的设置列表(数组),然后您可以按照您的需要对其进行排序/排序。因此,如果您希望第 3 个列表项成为第一个,则只需将其拖放到第一行即可。

我的猫鼬模式现在有问题。我正在寻找一种方法来实现 order 属性或允许我根据歌词的位置添加诸如 0 或 1 之类的 order 值的方法。你们有人知道如何最好地执行这样的命令吗?

这是我的架构的副本。目前,歌词是一组歌词对象 ID。但在那里我也需要一个“订单”,以便我可以根据订单值对数组进行排序。

const mongoose = require("mongoose");

const SetlistSchema = new mongoose.Schema({
    setlistName: { type: String, required: true },
    lastEdited: { type: Date },
    createdAt: { type: Date, default: Date.now },
    lyrics: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Lyric'
    }],
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User"
        },
        username: String
    }
});

module.exports = mongoose.model("Setlist", SetlistSchema);

这是歌词架构。

const mongoose = require("mongoose");

const LyricSchema = new mongoose.Schema({
    lyricName: { type: String, required: true },
    lyricContent: { type: String, required: true },
    lastEdited: { type: Date },
    createdAt: { type: Date, default: Date.now },
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User"
        },
        username: String
    }
});

module.exports = mongoose.model("Lyric", LyricSchema);

如果添加订单号不是最佳做法,那么您可以推荐什么方法来跟踪用户希望歌词显示的顺序?

【问题讨论】:

  • 你能在问题中添加歌词模式吗?
  • @SuleymanSah - 我现在添加了它。但是歌词模式与 setlist 模式有什么关系呢?我已经做到了,这样您就可以从歌曲列表中单独添加歌词。所以歌词需要以数组的形式添加到 setlists 中,但要使用顺序/排序号。
  • @SuleymanSah - 一开始我想在歌词中添加排序/顺序编号,但后来我意识到这首歌可以添加到多个 setlist 中,但不确定它是否具有所有这些中的相同索引号。所以我认为订单/排序号必须保存在 setlist 模式中。
  • 您是否有机会更新 Lyric 架构以保留列表 ID?
  • @SuleymanSah - 是的,我可以更新它,但我不确定它会有什么帮助。如果您的意思是我将 setlist objectId 保存在歌词模式中,这与我现在所做的有点相同,正好相反。因为现在我正在将歌词的 objectId 保存在 setlist 中。

标签: express sorting mongoose schema


【解决方案1】:

您可以使用聚合框架按顺序字段对歌词进行排序。您首先需要添加一个 Number 类型的排序字段。

Setlist.aggregate([
  {
    $unwind: "$lyrics"
  },
  {
    $lookup: {
      from: "lyrics",  // MUST be the PHYSICAL collection name
      localField: "lyrics",
      foreignField: "_id",
      as: "lyrics"
    }
  },
  {
    $sort: {
      "lyrics.order": 1
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "lyrics": {
        "$push": "$lyrics"
      },
      "allFields": {
        "$first": "$$ROOT"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          "$allFields",
          {
            "lyrics": "$lyrics"
          }
        ]
      }
    }
  }
])

Playground

示例文件:

db={
  "lists": [
    {
      "_id": ObjectId("5a934e000102030405000000"),
      "setlistName": "list1",
      "lastEdited": ISODate("2020-03-18T23:11:56.443+03:00"),
      "createdAt": ISODate("2020-03-15T23:11:56.443+03:00"),
      "lyrics": [
        ObjectId("6a934e000102030405000000"),
        ObjectId("6a934e000102030405000001"),
        ObjectId("6a934e000102030405000002")
      ]
    },
    {
      "_id": ObjectId("5a934e000102030405000001"),
      "setlistName": "list2",
      "lastEdited": ISODate("2020-03-11T23:11:56.443+03:00"),
      "createdAt": ISODate("2020-03-11T23:11:56.443+03:00"),
      "lyrics": [
        ObjectId("6a934e000102030405000003"),
        ObjectId("6a934e000102030405000004")
      ]
    }
  ],
  "lyrics": [
    {
      "_id": ObjectId("6a934e000102030405000000"),
      "name": "Lyric 1",
      "order": 3
    },
    {
      "_id": ObjectId("6a934e000102030405000001"),
      "name": "Lyric 2",
      "order": 1
    },
    {
      "_id": ObjectId("6a934e000102030405000002"),
      "name": "Lyric 3",
      "order": 2
    },
    {
      "_id": ObjectId("6a934e000102030405000003"),
      "name": "Lyric 4",
      "order": 2
    },
    {
      "_id": ObjectId("6a934e000102030405000004"),
      "name": "Lyric 5",
      "order": 1
    }
  ]
}

输出:(如您所见,歌词按顺序字段值排序)

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "createdAt": ISODate("2020-03-15T20:11:56.443Z"),
    "lastEdited": ISODate("2020-03-18T20:11:56.443Z"),
    "lyrics": [
      [
        {
          "_id": ObjectId("6a934e000102030405000001"),
          "name": "Lyric 2",
          "order": 1
        }
      ],
      [
        {
          "_id": ObjectId("6a934e000102030405000002"),
          "name": "Lyric 3",
          "order": 2
        }
      ],
      [
        {
          "_id": ObjectId("6a934e000102030405000000"),
          "name": "Lyric 1",
          "order": 3
        }
      ]
    ],
    "setlistName": "list1"
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "createdAt": ISODate("2020-03-11T20:11:56.443Z"),
    "lastEdited": ISODate("2020-03-11T20:11:56.443Z"),
    "lyrics": [
      [
        {
          "_id": ObjectId("6a934e000102030405000004"),
          "name": "Lyric 5",
          "order": 1
        }
      ],
      [
        {
          "_id": ObjectId("6a934e000102030405000003"),
          "name": "Lyric 4",
          "order": 2
        }
      ]
    ],
    "setlistName": "list2"
  }
]

【讨论】:

  • 感谢您的回答,但我认为这个行不通(或者我完全不明白)。如果我正确理解您的答案,那么每个歌词项目将具有相同的索引/订单号,无论它放置在哪个设置列表中。因此,如果将带有订单号 1 的歌词 1 放置在设置列表 1 中,它将具有订单号 1。并且如果它被放置在 Setlist 2 中,它也会有 1 号订单。但也许歌词“Song number 1”需要首先放在第一个 setlist 中,然后在第二个 setlist 中它可能需要放置为 5 号。
  • @MichaelØrregaardAndersen 如何正确更新是您的应用程序的职责。如果您保持顺序值一致,这将起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 2014-12-09
  • 2018-10-09
  • 2019-02-16
  • 2022-01-24
  • 2017-06-29
相关资源
最近更新 更多