简体   繁体   中英

mongoose - how to get subdocument to comply with a schema

So I have the following schemas:

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
    }
)

Now, Item_Detail is to be a subdocument of Item , but I'm not quite sure how I should enforce the default s and type restriction. I also don't want Item_Detail to be a collection in its own right, so using create or save probably doesn't fit.

I think you can use embedded documents for this so in your item schema you can embed an item_detail:

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

Then on the server when you want to add an item_detail you can do the following

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

then proceed to save it

myItem.save()

Enforcing the type is easy the default value is the tricky one but mongoose allows you to specify a function instead of boolean for default (just like it allows you the same for required ).

So you could do something like this (I shortened the schemas for bravity):

const itemDetails = new Schema({
  info: {
    type: String,
    required: true
  }
})

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

This would allow you to do something like this:

var itm = new Item();

And the saved result would be:

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

So this gives you two things:

  1. You cannot put any type in details other than itemDetails since you enforced the type with itemDetails .
  2. You initialize your ItemDetails object with defaults you want in your default custom function.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM