Last Updated
Viewed 11 Times
        
import * as mongoose from 'mongoose';
import { Document, Schema } from 'mongoose';

interface UserModelInterface extends Document {
  fruit: string
  zest: {
    color: string;
    size: string;
  };
}

const userSchema: Schema = new Schema(
  {
    fruit: { type: String },
    zest: {
      color: { type: String },
      size: { type: String },
    },
  },
  {
    timestamps: true,
  }
);

const userModel = mongoose.model<UserModelInterface>('User', userSchema);
export { userModel, UserModelInterface };

Then to save a new fruit... but how do I insert the size a sa child of zest?

import { userModel, UserModelInterface } from '../models/user';
...
const fruit = 'Pinapple';
const size = 'Large';
const user = new userModel({
  fruit,
  zest: {size}                     //<== Somthings wrong here?
} as UserModelInterface);
const saved = await user.save();

Then to update the record to add the color to zest withut effecting the size...

import { userModel, UserModelInterface } from '../models/user';
...
const fruit = 'Pinapple';
const color = 'Golden';
const confirmed = await userModel
  .findOneAndUpdate(
    { fruit },
    {
      $set: { zest: {color} },    //<== Somthings wrong here?

    }
  )
  .exec();
    ```

These are my schemas (Topic is parent and contains a list of 'Thought's):

var TopicSchema = new mongoose.Schema({
  title: { type: String, unique: true },
  category: String,
  thoughts: [ThoughtSchema]
}, {
  timestamps: true,
  toObject: {virtuals: true},
  toJSON: {virtuals: true}
});

var ThoughtSchema = new mongoose.Schema({
  text: String,
  author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
  votes:[{
    _id:false,
    voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
    up: Boolean,
    date: {type: Date, default: Date.now}
  }]
}, {
  timestamps: true,
  toObject: {virtuals: true},
  toJSON: {virtuals: true}
});

....

I am trying to read the thought's author and change my get Topic api like this:

...
  var cursor = Topic.find(query).populate({
    path: 'thoughts',
    populate: {
      path: 'author',
      model: 'User'
    }
  }).sort({popularity : -1, date: -1});

  return cursor.exec()
    .then(respondWithResult(res))
    .catch(handleError(res));
...

But the author is null.. i also do not get any error in the console. What is wrong here?

Edit: Actually i do not need the Thought as a schema, it does not have its own collection in database. It will be saved in topics. But in order to use timestamps option with thoughts, i needed to extract its contents to a new local schema ThoughtSchema. But i have now defined the contents of thoughtSchema directly in the thoughts array of topics, it still does not work.

Edit2: This is the cursor object just before it is executed. Unfortunately i cannot debug in Webstorm, this is a screenshot from node inspector:

enter image description here

Long time listener first time caller :-)

I've searched for a considerable amount of time and haven't quite found an answer to my problem here. I'm looking for a way, or would like to know the "proper" way, to only return a specific item within a nested mongoose Schema.

So lets say I have this example.

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

var conn = mongoose.connect('mongodb://localhost/testjs');

Bar = new Schema({
  text: String
});

Foo = new Schema({
  bar: [Bar]
});

var Foo = mongoose.model('Foo', Foo);

// Clean up the DB
Foo.find({}, function(err, res) {
    for (i in res) {
        res[i].remove()
    }
});

var foo = new Foo()
foo.bar.push({"text":"Hi"})
foo.bar.push({"text":"Bye"})
foo.bar.push({"text":"Hey"})

foo.save(
  function(err){

    var r = Foo
    .where('bar.text').equals('Hi')
    .select('bar.text')
    .exec(function(err, res) {
        console.log(res)
    })
  }
);

Result

[ { _id: 546c235cea0f16dc0d85a60f,
    bar: [ { text: 'Hi' }, { text: 'Bye' }, { text: 'Hey' } ] } ]

From the query I would've expected it to only return

[ { _id: 546c235cea0f16dc0d85a60f,
        bar: [ { text: 'Hi' } ] } ]

So I guess that leads me to a few questions:

  1. Is there a better way this query should be constructed?
  2. Is this typical behavior and it's up to be to loop over the results and just pull out what I need?
  3. For the original query, why would it return all fields rather than what I've specified in the 'where' statement?

This question already has an answer here:

Using moongoose for Node.js, I'm trying to go through each object in the "STEPS" array and decrease the stepid by 1. Using this schema below:

"appid": 1,
"steps": [
            {
                "name": "step4",
                "stepid": 4,
            },
            {
                "name": "step5",
                "stepid": 5,
            }               
         ],
"appname": "myapp"

Here's how I tried is using .update:

app.db.models.myApps.update(
        {'appid': 1, 'steps.stepid': { $gt: 3 }},
        { $inc: { 'steps.$.stepid': -1 } },
    { multi: true }
);

But I can't seem to get it to work correctly. I was able to play around with the code and get it to update but it would only update 1 of the objects in the array, whereas I would like it to go through each object in the array and decrease by 1.

Should I break it out and first use find and then update? The old dev in me says to do a for loop but I know that's not the right way to do it with node.

Any help or suggestions are greatly appreciated! Thanks!

Similar Question 4 (1 solutions) : Mongoose Save Nested Array of Objects - Node.js

Similar Question 7 (1 solutions) : Mongoose: Schema for nested Json and store it (Node.js)

Similar Question 9 (1 solutions) : Node.js: Updating a document with Mongoose

cc