These are chat archives for Automattic/mongoose

15th
Jul 2016
awei.yu
@aweiu
Jul 15 2016 05:10

document:

{
  children:[
    {
      name:'tom'
    },
    {
      name:'jack'
    }
  ]
}

how to get the sub-doc named 'jack'?
don't use that:

  parent.find({},(e,doc) => {
    doc...
  })
Hengki Sihombing
@hengkiardo
Jul 15 2016 05:46
anyone have the problem with mongoose@4.4.4
i have suddently problem with connection and permission for insert/query
'use strict'

module.exports = function (config, mongo) {
  var options = {
    server: {
      socketOptions: {
        keepAlive: 1,
        // poolSize:5,
        connectTimeoutMS: 30000
      }
    },
    replset: {
      socketOptions: {
        keepAlive: 1,
        // poolSize:5,
        connectTimeoutMS: 30000
      }
    }
  }

  mongo.connect(config.url, options)

  var conn = mongo.connection

  conn.on('connected', function () {

  })

  // Error handler
  conn.on('error', function (err) {
    if (err) {
      console.error('✗ MongoDB Connection to ' + config.url + ' is Error. Please make sure MongoDB is running. -> ' + err)
    }
  })

  var gracefulExit = function () {
    conn.close(function () {
      // console.info('Mongoose default connection with DB :' + config.url + ' is disconnected through app termination')
      process.exit(0)
    })
  }

  // If the Node process ends, close the Mongoose connection
  process.on('SIGINT', gracefulExit).on('SIGTERM', gracefulExit)

  return conn
}
that sample connection i have one
awei.yu
@aweiu
Jul 15 2016 05:49
@aredo i don't kown.. the chat room seems like no one online
Hengki Sihombing
@hengkiardo
Jul 15 2016 05:49
the error like this one
not authorized for query on production-mongo-urbanhire.collections
awei.yu
@aweiu
Jul 15 2016 05:51
i remember the collection name can't include '-'
Hengki Sihombing
@hengkiardo
Jul 15 2016 06:02
i see
awei.yu
@aweiu
Jul 15 2016 06:03
ok.could i ask you some question?
Hengki Sihombing
@hengkiardo
Jul 15 2016 06:04
yes
awei.yu
@aweiu
Jul 15 2016 06:06
how can i get the last inserted of sub-doc?
the document is:
  {
    children:[
      {
        create_time:xxxx
      },
      {
        create_time:xxxx2
      }
    ]
  }
i want the last one of that children
Hengki Sihombing
@hengkiardo
Jul 15 2016 09:24
i dont expert on query and aggregation
you query first and filter/mapping by lodash or another libs
Mohamed Nasrullah
@nasr18
Jul 15 2016 09:25
get children's data and use reverse array.
Can
@canoztokmak
Jul 15 2016 11:24
hey people.. i'm having an issue where mongoose doesn't let me to use $exists for _id field.. i've tried to pull elements from an array that doesn't have _id field.. it said "Can't use $exists with ObjectId." .. then i tried to remove the element by .remove() function, and in that case it said "For your own good, Mongoose does not know how to remove an EmbeddedDocument that has no _id" ... so, i wonder if there is a way to remove those elements from the array ? by the way, why can't we use $exists for _id field ?
Alann Sapone
@devoluti0n
Jul 15 2016 16:03
Hello everyone - Definitely loving this ODM - Still, I'm struggling with saving nested schemas when I save parents.
I have 2 tables : parents and children
I want to automatically save all children when a parent is saved.
The parent saves correctly (children array get the children ids) but the children doesn't get saved in their tables... How can I do ? Thx :)
Martin Reynolds
@Hobbit71
Jul 15 2016 17:00
Hi @devoluti0n , are you talking about subDocument or is it genuinely two collections (tables)?
Also, how are you adding children to the parent, are you using parent.childen.push(…) ?
Alann Sapone
@devoluti0n
Jul 15 2016 17:01
No, I am adding children client side :)
Hi btw ^^
Martin Reynolds
@Hobbit71
Jul 15 2016 17:01
Hi
Alann Sapone
@devoluti0n
Jul 15 2016 17:02
In fact, I have an client-side object, which have the same structure as the one declared in my models
which is my parent item
So I add my children client side, into my parent item
Martin Reynolds
@Hobbit71
Jul 15 2016 17:02
So I have some code that adds a child and then saves the document, looks like this
  .post(function(req, res){
    var now = new Date();

    Notifications
      .findById(req.body.messageid)
      .populate('viewers')
      .exec(function(err, found){
        if (err) {
          res.sendStatus(500);
          return;
        }

        found.viewers.push({ userid: req.params.userid, when: now });
        found.save(function(err){
          if (err) res.sendStatus(500);
          else res.sendStatus(204);
        });
      });
Alann Sapone
@devoluti0n
Jul 15 2016 17:03
And then, with angular resource, I request a POST or PUT to my server on the parent itself
Martin Reynolds
@Hobbit71
Jul 15 2016 17:04
so this is my web service to post a notification update acknowledgement for a message
Alann Sapone
@devoluti0n
Jul 15 2016 17:04
Hmm, so you suggest me to iterate trough each children, and use push on the found item
Martin Reynolds
@Hobbit71
Jul 15 2016 17:04
once I have my document, oush the new child document and save the parent document.
You are passing all the children back in array to your web service
Alann Sapone
@devoluti0n
Jul 15 2016 17:05
I'm passing the parent, already containing all children
Martin Reynolds
@Hobbit71
Jul 15 2016 17:06
Is a new document or a document to update?
Alann Sapone
@devoluti0n
Jul 15 2016 17:06
Can be both
It's a litle bit complicated
But let's say it's an update :)
With ng resource, I send a PUT request to the server
trough express, I have the req object
req.body contains all my object, with children in an array
Martin Reynolds
@Hobbit71
Jul 15 2016 17:08
OK - understood
So if it is an update you still need to find the parent record first right
Alann Sapone
@devoluti0n
Jul 15 2016 17:09

then, what I do is var parent = req.parent
parent.children = req.body.children

parent.save(function (err) {
.....

No, I don't have to find the parent record, I can actually directly call save on it
Maybe it's a feature included in my MEAN.JS stack, not sure :worried:
Martin Reynolds
@Hobbit71
Jul 15 2016 17:10
OK, I am with what you are trying to do. Suprised at the parent save but cool that it works :)
I have had the issue with children saving which is why I responded
In your code can you try something like this
var parent = req.parent;
parent.populate(‘children’);
parent.children = req.body.children;
parent.save(…);
Alann Sapone
@devoluti0n
Jul 15 2016 17:14
Trying this in a sec :), ty !
Nope :(, populating doesn't change anything
in the case I tried
Martin Reynolds
@Hobbit71
Jul 15 2016 17:17
boo!
Alann Sapone
@devoluti0n
Jul 15 2016 17:17
What I did was :
Insert a child in my parent
executing a put request on the parent
it didn't create the child :(
Which is weird is that from my parent, i correctly have the child id
but the child table is empty :(
Btw, sorry for my bad english, I'm french, :p
Martin Reynolds
@Hobbit71
Jul 15 2016 17:21
That’s OK. Sorry for my bad English I am from England ;)
Alann Sapone
@devoluti0n
Jul 15 2016 17:21
lol
Martin Reynolds
@Hobbit71
Jul 15 2016 17:22
I can’t work out how this line is working var parent = req.parent;
Alann Sapone
@devoluti0n
Jul 15 2016 17:22
The only way I found to insert my children was to use the pre('save') hook
I'm using a mean stack called MEAN.JS
Maybe it's an underlayed feature, not sure
Martin Reynolds
@Hobbit71
Jul 15 2016 17:22
OK - let me take a quick look at that - brb
So it is a boilerplate project
Alann Sapone
@devoluti0n
Jul 15 2016 17:23
Thanks a lot !
Meanwhile, I'll try the first solution you brought me to check if there is a difference. (the one with find)
yes
Martin Reynolds
@Hobbit71
Jul 15 2016 17:23
ok
Alann Sapone
@devoluti0n
Jul 15 2016 17:26
Exactly the same behaviour :(
Project.findById(req.body._id).populate('components').exec(function (err, found) {
    if (err) {
      res.sendStatus(500);
      return;
    }

    for (var i = 0; i < req.body.components.length; i++) {
      found.components.push(req.body.components[i]);
    }
    found.save(function (err) {
      if (err)
        res.sendStatus(500);
      else
        res.sendStatus(204);
    });
  });
This message was deleted
Martin Reynolds
@Hobbit71
Jul 15 2016 17:31
var Parent = mongoose.model('Parent');
var parent = new Parent;

// create a comment
parent.children.push({ name: 'Liesl' });
var subdoc = parent.children[0];
console.log(subdoc) // { _id: '501d86090d371bab2c0341c5', name: 'Liesl' }
subdoc.isNew; // true

parent.save(function (err) {
  if (err) return handleError(err)
  console.log('Success!');
});
This is what is in mongoose documentation for saving a subdocument
Alann Sapone
@devoluti0n
Jul 15 2016 17:32
Trying this in a second, this isNew flag might be my hero !
Martin Reynolds
@Hobbit71
Jul 15 2016 17:34
You can also add a new subdocument like this
var newdoc = parent.children.create({ name: 'Aaron' });
Alann Sapone
@devoluti0n
Jul 15 2016 17:35
1st one not working, same behaviour
Martin Reynolds
@Hobbit71
Jul 15 2016 17:35
You could also check if the parent knows it has been modified parent.modified
Alann Sapone
@devoluti0n
Jul 15 2016 17:35
create function not defined :p
Martin Reynolds
@Hobbit71
Jul 15 2016 17:35
ha
sorry post 3.x parent.isModified()
Alann Sapone
@devoluti0n
Jul 15 2016 17:38
I'm pretty sure the parent part is okay, as it's saving correctly on its side :p
Martin Reynolds
@Hobbit71
Jul 15 2016 17:38
or even parent.isModified(‘children’)
Alann Sapone
@devoluti0n
Jul 15 2016 17:38
hmm ok, testing right now :)
Same behaviour :'(
Martin Reynolds
@Hobbit71
Jul 15 2016 17:39
found.markModified(‘components’);
Alann Sapone
@devoluti0n
Jul 15 2016 17:40
child Id being save in the parent, child not being created
Trying :D
Still the same
Is it possible my schemas are wrong ?
Martin Reynolds
@Hobbit71
Jul 15 2016 17:41
so wait, the data is saving in the parent not the child. How did you define the schema in Mongoose (your Project prototype)
That is what I just thought - hence my question
Alann Sapone
@devoluti0n
Jul 15 2016 17:41
var ProjectSchema = new Schema({
.....
components: [{
type: Schema.ObjectId,
ref: 'Component',
unique: true
}]
Project is the parent, components in the array of child
then component is a whatever schema
Martin Reynolds
@Hobbit71
Jul 15 2016 17:42
this is what mine looks like
var mongoose = require('mongoose');

var viewed = mongoose.Schema({ userid: String, when: Date});

var notification = mongoose.Schema({
  title: String,
  body: String,
  publish: Date,
  expire: Date,
  severity: String,
  mustConfirm: Boolean,
  viewers: [viewed],
  created: Date,
  modified: Date
});
Alann Sapone
@devoluti0n
Jul 15 2016 17:43
But if I don't use Schema.ObjectId, how can I tell him to store the child in an another table ?
You have two tables, right ? viewed and notification ?
Martin Reynolds
@Hobbit71
Jul 15 2016 17:45
By table you mean collection. So if you looked in mongodb you expect to see Project and Components as 2 separate collections.
I have viewers as a direct subdocument of notifications. So I have a single collection called notifications
Alann Sapone
@devoluti0n
Jul 15 2016 17:45
right, collections, sorry :p
That's what I tough
I need to separate my children in a separate collection
And use a reference with _id
on the parent
In my case
I have 2 collections :
  • projects
  • components
Martin Reynolds
@Hobbit71
Jul 15 2016 17:47
Understood. In that case you can’t use the syntax we were talking about previously.
Alann Sapone
@devoluti0n
Jul 15 2016 17:47
I guess :(
Martin Reynolds
@Hobbit71
Jul 15 2016 17:47
Give me a couple of minutes to think about the best way to handle that
I will get myself a coffee and brb
Alann Sapone
@devoluti0n
Jul 15 2016 17:48

Okay, fyi, I managed to make it work with schema.pre('save .... ) middleware

then inside I save all my components.
But I don't think it's a clean way to do it :'(

Btw, thanks a lot, that's very very kind of you
Martin Reynolds
@Hobbit71
Jul 15 2016 17:57
When you create components model is it something like
var Components = mongoose.model(‘components’, ComponentsSchema);
This message was deleted
Alann Sapone
@devoluti0n
Jul 15 2016 18:00
Hmm, no. I sure have
mongoose.model('Component', ComponentSchema);
but as I said, the components are created client side
Martin Reynolds
@Hobbit71
Jul 15 2016 18:01
I know but the model will need to be at server side
Alann Sapone
@devoluti0n
Jul 15 2016 18:01
the model is server side
Martin Reynolds
@Hobbit71
Jul 15 2016 18:01
great
Alann Sapone
@devoluti0n
Jul 15 2016 18:02
Let me show you my simple update of project :p
    exports.update = function (req, res) {
    var project = req.project;

    project.components = req.body.components;
    project.name = req.body.name;
    project.description = req.body.description;
    project.assistants = req.body.assistants;

    project.markModified('components');

    project.save(function (err) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.json(project);
      }
    });

  };
Martin Reynolds
@Hobbit71
Jul 15 2016 18:03
Sure. I think I know what the issue is.
Alann Sapone
@devoluti0n
Jul 15 2016 18:03
Juste removed the mark modified, was useless
So you think I should use new on each entry
that make sense :)
(if they don't have an _id, I guess)
Martin Reynolds
@Hobbit71
Jul 15 2016 18:04
You need to save each component to the components collection so it has an ID
you then need to update the Project with the array of IDs
Alann Sapone
@devoluti0n
Jul 15 2016 18:05
That's what I did too, with the pre('save', func...) hook
But I tought there was something easier
not that it's hard
Just, it seems strange to me
Martin Reynolds
@Hobbit71
Jul 15 2016 18:06
So simplifying I think schemas should look like this
var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var ProjectSchema = new Schema({
    name    : String
  , components : [{ type: Schema.ObjectId, ref: ‘Component' }]
});

var ComponentsSchema = new Schema({
  , data    : String
  , data     : String
});

var Project  = mongoose.model(‘Project', ProjectSchema);
var Component = mongoose.model(‘Component', ComponentSchema);
then to add the components you would do project.components.push(comp1)
Martin Reynolds
@Hobbit71
Jul 15 2016 18:11
but you can only do that after inserting/updating components
The component has to be saved first (so it has an ID) before you can push it to the Project
You only need to push NEW components to the project, existing ones will pick up from components table
You have to process req.body.components so all the ids are populated
what does the saved document look like right now in mongodb when you query the Projects collection?