【问题标题】:mongoose - how to get subdocument to comply with a schema猫鼬 - 如何让子文档符合模式
【发布时间】:2018-08-15 04:27:54
【问题描述】:

所以我有以下架构:

var Item_Detail = new Schema(
    {
        content: {
            index: true,
            type: Array
        },
        is_private: {
            default: false,
            index: true,
            type: Boolean
        },
        order: {
            index: true,
            required: true,
            type: Number
        },
        table: {
            default: {},
            type: Object
        },
        title: {
            required: true,
            index: true,
            type: String,
        },
        type: {
            default: "text",
            enum: ["text", "table"],
            index: true,
            type: String
        },
    },
    {
        strict: false
    }
)

const Item = new Schema(
    {
        details: {
            default: [],
            index: true,
            type: [Item_Detail],
        },
        display_name: {
            default: "",
            index: true,
            type: String,
        },
        image: {
            default: "http://via.placeholder.com/700x500/ffffff/000000/?text=No%20Image&",
            type: String
        },
        is_private: {
            default: false,
            index: true,
            type: Boolean
        },
        tags: {
            index: true,
            type: [Tag]
        }
    },
    {
        strict: false
    }
)

现在,Item_Detail 将成为Item 的子文档,但我不太确定应该如何执行defaults 和type 限制。我也不希望Item_Detail 本身就是一个集合,所以使用createsave 可能不适合。

【问题讨论】:

  • 所以您想在Item Schema 详细信息中引用type 和项目详细信息的_id 以及defaults 数组中的内容?
  • @Akrion 默认可以是一个空数组
  • type 怎么样,你想在里面有什么?项目架构的交叉引用 ID?如果是这样,那么您只需要添加一个ref
  • @Akrion type 只是一个字符串。 Item_DetailsItem 的子文档,它不应该独立存在,即作为一个集合。
  • 只将 Item_id 放入 Item_Detail... 并使用 $lookup 聚合来获取它们

标签: javascript mongodb mongoose mongoose-schema


【解决方案1】:

我认为您可以为此使用embedded documents,因此您可以在您的项目架构中嵌入 item_detail:

const Item = new Schema({
    ...
    item_detail: item_detail
})

然后在服务器上,当您要添加 item_detail 时,您可以执行以下操作

myItem = new Item({//enter item data here})
//assign item detail here
myItem.item_detail = item_detail ;

然后继续保存

myItem.save()

【讨论】:

    【解决方案2】:

    强制类型很容易,默认值是棘手的,但mongoose 允许您使用specify a function 而不是default 的布尔值(就像它允许您使用same for required 一样)。

    所以你可以做这样的事情(我为了勇敢而缩短了模式):

    const itemDetails = new Schema({
      info: {
        type: String,
        required: true
      }
    })
    
    const item = new Schema({
      details: {
        default: function() {
          return [new ItemDetails({ info: 'N/A' })]
        },
        type: [itemDetails],
      }
    })
    

    这将允许您执行以下操作:

    var itm = new Item();
    

    保存的结果是:

    {
      "_id": ObjectId("5b72795d4aa17339b0815b8b"),
      "details": [{
        "_id": ObjectId("5b72795d4aa17339b0815b8c"),
        "info": "N/A"
      }]
    }
    

    所以这给了你两件事:

    1. 您不能在details 中添加除itemDetails 之外的任何类型,因为您使用itemDetails 强制了该类型。
    2. 您可以在 default 自定义函数中使用所需的默认值初始化 ItemDetails 对象。

    希望这会有所帮助。

    【讨论】:

    • 我不明白为什么我不能将default 移动到itemDetails info 中?我的问题是 table 没有被初始化。
    • 好的,但您在问题中没有提到任何关于 table 的内容。我只是举一个例子,你可以使用default作为一个函数来初始化你想要的anything...包括表格。
    • 另外请注意 Mongoose 没有类型 Object 而是 Mixed 所以你可以创建表 Mixed 然后使用 default 以任何你想要的方式初始化它。
    猜你喜欢
    • 2021-07-22
    • 2016-06-17
    • 2017-06-06
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 2015-10-01
    • 2021-10-06
    相关资源
    最近更新 更多