简体   繁体   中英

Cannot push subdocuments to a document's array in Mongoose

I am trying to push a bunch of subdocuments to a document's array. What am i doing wrong?

The error and the code is provided below.

Error:

21:28:49 web.1  | { [CastError: Cast to undefined failed for value "{ url: 'http://www.bbc.co.uk',
21:28:49 web.1  |   _id: 55a17c812424c54413de3332,
21:28:49 web.1  |   entities: [],
21:28:49 web.1  |   terms: [] },{ url: 'http://www.google.com',
21:28:49 web.1  |   _id: 55a17c812424c54413de3333,
21:28:49 web.1  |   entities: [],
21:28:49 web.1  |   terms: [] }" at path "documents"]
21:28:49 web.1  |   stack: 'Error\n    at MongooseError.CastError (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/error/cast.js:18:16)\n    at SchemaArray.cast (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/schema/array.js:157:15)\n    at Query._castUpdateVal (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/query.js:2270:22)\n    at Query._walkUpdatePath (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/query.js:2240:25)\n    at Query._castUpdate (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/query.js:2118:23)\n    at Query.update (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/query.js:1959:22)\n    at Function.update (/Users/martynas/Desktop/sandbox/osint-api/node_modules/mongoose/lib/model.js:1734:13)\n    at exports.populateCase (/Users/martynas/Desktop/sandbox/osint-api/app/controllers/case.js:69:10)\n    at Layer.handle [as handle_request] (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/layer.js:82:5)\n    at next (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/route.js:100:13)\n    at Route.dispatch (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/route.js:81:3)\n    at Layer.handle [as handle_request] (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/layer.js:82:5)\n    at /Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/index.js:234:24\n    at param (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/index.js:331:14)\n    at param (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/index.js:347:14)\n    at Function.proto.process_params (/Users/martynas/Desktop/sandbox/osint-api/node_modules/express/lib/router/index.js:391:3)',
21:28:49 web.1  |   message: 'Cast to undefined failed for value "{ url: \'http://www.bbc.co.uk\',\n  _id: 55a17c812424c54413de3332,\n  entities: [],\n  terms: [] },{ url: \'http://www.google.com\',\n  _id: 55a17c812424c54413de3333,\n  entities: [],\n  terms: [] }" at path "documents"',
21:28:49 web.1  |   name: 'CastError',
21:28:49 web.1  |   kind: undefined,
21:28:49 web.1  |   value: [{"url":"http://www.bbc.co.uk","_id":"55a17c812424c54413de3332","entities":[],"terms":[]},{"url":"http://www.google.com","_id":"55a17c812424c54413de3333","entities":[],"terms":[]}],
21:28:49 web.1  |   path: 'documents' }

Case:

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;
var Document = require('./document');

var CaseSchema = ({
    documents: [Document]
});

module.exports = mongoose.model('Case', CaseSchema);

Document:

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var DocumentSchema = ({
    url: String
});

module.exports = mongoose.model('Document', DocumentSchema);

Code:

'use strict';

var mongoose = require('mongoose');
var Case = mongoose.model('Case');
var Document = mongoose.model('Document');

exports.populateCase = function(req, res) {

    var caseId = req.params.caseId;

    var doc1 = new Document({
        url: 'http://www.bbc.co.uk'
    });
    var doc2 = new Document({
        url: 'http://www.google.com'
    });

    Case.update({_id: caseId}, {$pushAll: { documents: [doc1, doc2] }}, {upsert: true}, function(err) {
        if (err) {
            console.log(err);
        } else {
            console.log('YAY!');
        }
    });
};

Sub-documents need to be a mongoose Schema, not a mongoose Model. You would need to to specify

var CaseSchema = ({
    documents: [Document.DocumentSchema]
});

or, you can just put your DocumentSchema variable declaration inside your case.js file, and use

var CaseSchema = ({
    documents: [DocumentSchema]
});

Also, change your Document declaration in your case.js file to be

var Document = mongoose.model('Document');

Depending on how you are loading all your model files, you may have to add to the code

require('./document.js');
require('./code.js');

You can try this way:

Case

var mongoose = require('mongoose'),
    Schema = mongoose.Schema
var CaseSchema = ({
  documents: [{type: Schema.Types.Object, ref: 'Document' }]
});

var Case = mongoose.model('Case', CaseSchema);
module.exports = Case

Document

var mongoose = require('mongoose'),
    Schema = mongoose.Schema

var DocumentSchema = ({
    url: String
});

module.exports = mongoose.model('Document', DocumentSchema);

App

var Document = require('./Document')
var Case = require('./Case')

var doc1 = new Document({
    url: 'http://www.bbc.co.uk'
});
var doc2 = new Document({
    url: 'http://www.google.com'
});


Case.update({_id: caseId}, {$pushAll: { documents: [doc1, doc2] }}, {upsert: true}, function(err) {
    if (err) {
        console.log(err);
    } else {
        console.log('YAY!');
    }
});

I have disabled "_id" field and added custom "_id" field of type "String" in case model. In my solution it uses db_manager (you don't need it) file from old template for the connection to database (you can use default one).

Case:

var mongoose = require('mongoose');
var Document = require('./document');
var dbManager = require('./../configuration/db_manager.js');
var Schema = mongoose.Schema;

var CaseSchema = new Schema({
  _id: String,
  documents: [Document.schema]
}, {
  _id: false
});

exports.schema = CaseSchema;
exports.model = dbManager.appConnection.model('Case', CaseSchema);

Document:

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;
var dbManager = require('./../configuration/db_manager.js');

var DocumentSchema = new Schema({
  url: String
});

exports.model = dbManager.appConnection.model('Document', DocumentSchema);
exports.schema = DocumentSchema;

Code

exports.populateCase = function(req, res) {
  var caseId = req.params.caseId;

  var doc1 = new documentDbModel.model({
      url: 'http://www.bbc.co.uk'
  });

  var doc2 = new documentDbModel.model({
      url: 'http://www.google.com'
  });

  var docs = [doc1, doc2];

  caseDbModel.model.update({
    "_id": caseId
  }, {
    "$pushAll": {
      "documents": docs
    }
  }, {
    "upsert": true
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      console.log('YAY!');
    }
  });
};

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