0

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!');
        }
    });
};

3 Answers 3

2

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!');
    }
});
Sign up to request clarification or add additional context in comments.

3 Comments

This way though means you are only storing the Id of Documents, and in order to access those documents elements, you would have to do a .populate() on them.
Nope, it would save entire object since type is Object not ObjectId.
Oops, I didn't notice you specified Object and not ObjectId.
2

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');

2 Comments

I think you're headed to the right direction here :-) However, i'm getting an error when using the first example: TypeError: Invalid value for schema Array path documents. The schema declarations need to be in separate files. How can i achieve this?
I forgot to add in the last part. change Document in your case.js file to be var Document = mongoose.model('Document');
0

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!');
    }
  });
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.