Mongoose - Generate ObjectID for each object before saving document

前端 未结 2 745
遥遥无期
遥遥无期 2021-01-15 15:43

I want generate an ObjectID for each Object present inside my array. The thing is I\'m getting the products with a .forEach statement from another server and push them insid

相关标签:
2条回答
  • 2021-01-15 15:58

    If you want to add ObjectId automatically, you need to define a separate schema for it and set the _id options for the schema as true.

    Do the following:

    • Change your productsSchema as CatalogueSchema (for ease of understanding).
    • Define a new ProductSchema for Product (element of allProducts)
    • In CatalogueSchema define allProducts type as [Product.schema]. This will automatically add _id (ObjectId).

    Also, you don't need to add created_at and updated_at as part of schema when you set timestamps option as true.

    Catalogue Schema

    const Product = require('Product_Schema_Module_Path'); // Edit
    
    const CatalogueSchema = new mongoose.Schema({
    
        apiKey: String,
        domain: String,
        totalcount: Number,
        totaldone: Number,
        allSKUS: Array,
        allProducts: [Product.schema]   
        // Note the change here (Array -> [Product.schema]
      // Creating a separate schema ensures automatic id (ObjectId)
    
    }, { collection: 'catalogue', timestamps: true });
    
    CatalogueSchema.plugin(uniqueValidator);
    
    const Catalogue = mongoose.model('Catalogue', CatalogueSchema);
    module.exports = Catalogue;
    

    Product Schema (New schema to ensure adding of ObjectId)

    const ProductSchema = new mongoose.Schema({
    
        id: Number,
        sku: String,
        name: String,
        status: Number,
        total_images: Number,
        media_gallery_entries: Array
    
    }, { _id: true, timestamps: true });  
    // _id option is true by default. You can ommit it.
    // If _id is set to false, it will not add ObjectId
    
    ProductSchema.plugin(uniqueValidator);
    
    const Product = mongoose.model('Product', ProductSchema);
    module.exports = Product;
    

    EDIT (Save Products in Catalogue)

    (Also, note that you have to require the ProductSchema module in your CatalogueSchema module)

    // Map userApiProducts.allProducts to array of Product documents
    const products = userApiProducts.allProducts.map(product => {
        return new Product(product);
    })
    
    const newProduct = {
        apiKey: userApiProducts.apiKey,
        domain: userApiProducts.domain,
        totalcount: userApiProducts.totalcount,
        totaldone: userApiProducts.totaldone,
        allSKUS: userApiProducts.allSKUS,
        allProducts: products
    };
    
    Catalogue
        .findOneAndUpdate({ domain: userApiProducts.domain }, newProduct, { upsert:true } , (err, products) => {
        // Handle error
    });
    
    0 讨论(0)
  • 2021-01-15 16:04

    To add multiple documents into Mongo you can use db.collection.insert():

    • https://docs.mongodb.com/manual/reference/method/db.collection.insert/

    In Mongoose you can use Model.insertMany():

    • http://mongoosejs.com/docs/api.html#model_Model.insertMany

    But keep in mind that when you have one document inside of other document in Mongoose they are not actually stored like that in Mongo. Mongo only stores the IDs of the child documents and not their contents in the parent document - and not even any info on which collection those IDs belong to.

    When you use population then Mongoose actually retrieves the relevant documents from the DB in separate requests to Mongo. So, population is a concept of Mongoose. Mongo just stores the IDs, so you need to create the documents first before you can insert the IDs.

    The thing that you are trying to do would be easy without using Mongoose. You can store multiple documents in one request in Mongo using your own IDs if you want and you can store another document with an array of those IDs in another request.

    Of course however you do it you will get inconsistent state during the operation because Mongo doesn't support transactions.

    0 讨论(0)
提交回复
热议问题