What's the difference between document.property and document.get('property')? - javascript

I have a mongoose document that has timestamps option enabled. I want to make decisions based on this timestamps but I noticed something weird according to my understanding.
I tried to get those values the traditional way (document.createdAt) but that returns undefined. But if I use document.get('createdAt') the value comes as in the database. The docs don't say anything about this. My question is: ¿Why timestamps behave this way?
Edit
The schema I'm using has an array of embedded schemas:
const Customer = new mongoose.Schema({
roles: {
type: [{
type: String,
enum: 'app b2b iot'.split(' '),
}],
default: 'app',
set: (value = []) => (value.includes('app')
? value
: value.concat('app')),
},
email: {
address: {
type: String,
trim: true,
lowercase: true,
set(email) {
this._previousEmail = this.email.address
return email
},
},
verified: {
type: Boolean,
},
token: String,
},
nickname: {
type: String,
trim: true,
},
recoveryToken: String,
gender: String,
birthday: String,
lastLogin: Date,
isAnonymous: {
type: Boolean,
default: false,
},
devices: [Device],
});
Device schema:
const Device = new mongoose.Schema({
customer: {
type: ObjectId,
ref: 'Customer',
required: true,
},
handle: {
type: String,
},
platform: {
type: String,
required: true,
set: toLowerCase,
},
info: Mixed,
smartFilterTags: [{
type: String,
}],
paidUntil: Date,
nh: {
tier: String,
_id: {
type: ObjectId,
},
location: {
type: {
type: String,
enum: ['Point'],
default: 'Point',
},
coordinates: [{
type: Number,
}],
},
})
I have a base plugin that apply when I compile models:
function basePlugin(schema) {
schema.add({
archivedAt: Date,
})
schema.set('timestamps', true)
schema.set('toJSON', {
virtuals: true,
})
schema.set('toObject', {
virtuals: true,
})
}

Related

How to make a mongoose schema of arrays with nested subdocuments

I want to store an array of nested subdocuments such as the one down bellow:
[
{"2021-02-01income":{"value":37.95,"tax":0,"type":"income"}},
{"2021-03-01income":{"value":38.25,"tax":0,"type":"income"}},
{"2021-03-08fund": {"value":-78,"type":"fund","transaction":"610378deead56742a898443b"}},
{"2021-04-01income":{"value":38.53,"tax":0,"type":"income"}},
{"2021-07-01income":{"type":"income","tax":0,"value":134}},
]
I came up with the following schema which is not working, because as you can see the array of objects is based on unique keys nested objects...
Is there any workaround I can try:
const incomeSchema = mongoose.Schema({
type: { type: String, required: true },
value: { type: Number, required: true },
tax: { type: Number, required: false },
transaction: {
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: 'Transaction',
},
});
const investmentSchema = mongoose.Schema(
{
incomes: [{ type: incomeSchema }],
name: { type: String, required: true },
user: {
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: 'User',
},
account: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Account',
},
broker: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Broker',
},
type: { type: String, required: true },
rate: { type: String, required: true },
indexer: { type: String, required: true },
investment_date: { type: Date, required: true },
due_date: { type: Date, required: true },
initial_amount: { type: Number, required: true },
accrued_income: { type: Number, required: false, default: 0 },
taxes: { type: Number, required: false, default: 0 },
},
{ timestamps: true }
);
const Investment = mongoose.model('Investment', investmentSchema);
I found a workaround.... I just setted the _id in the Transaction schema as string and now everything is working... I mean I can update the array of neste subdocuments

How to unbind nested objects, result of an one to many relationship with aggregate mongo

I need help with mongo, I need to make a query resulting in a objext and many object nested resulting of a one to many relation ship of these schemas:
const ProductSchema = new Schema({
name: { type: String, required: true, unique:true },
picture: { type: String },
description: { type: String, required: true },
isEnabled: { type: Boolean, required: true },
brand: { type: Schema.Types.ObjectId, ref:'Brand' },
slug: { type: String, required: true },
category: { type: mongoose.Schema.Types.ObjectId, ref:'Category' },
reviews: [{ type: mongoose.Schema.Types.ObjectId, ref:'Review' }]
const PackageSchema = new Schema({
type: { type: String, enum:["WEIGHT", "EACH"], required: true },
value: { type: Number, required: true },
price: { type: Number, required: true },
stock: { type: Boolean, required: true},
description: { type: String, required: true},
product: { type: mongoose.Schema.Types.ObjectId, ref:'Product', required: true },
dispensary: { type: mongoose.Schema.Types.ObjectId, ref:'Dispensary', required: true }
This is the code i made
const dispensaryID;
payload = _thisModel.aggregate([
{
$lookup:{
from: "packages",
localField:'_id',
foreignField:'product',
as:"package"
}
},
{"$unwind": {path:"$package", preserveNullAndEmptyArrays: true}} ,
{
$group:
{
_id:"$_id",
number: {
$sum: "$package"
},
package: {$push: '$package'},
}
},
],(aggErr, aggResult) => {
(aggErr) ? console.log(aggResult)
: console.log(aggResult)
})
Buy it is resulting on this:
{ _id: 5ebf98724ef6e503ccd7ae4f, clicks: 0, package: [ [Object] ] },
{
_id: 5ebf98614ef6e503ccd7ae4e,
clicks: 0,
package: [ [Object], [Object], [Object], [Object] ]
},
{ _id: 5ebed37b52ec0043fca22893, clicks: 0, package: [] }
So i need to unbind those objects, I need to see the packages details instead some "[Object]", I tried reconfiguring the script but this is the nearest result I got, also I need to check if a dispensary: { type: mongoose.Schema.Types.ObjectId, ref:'Dispensary', required: true } given in the second schema exists in any of those packages, I will give a const to check if it maches, and add a prop says exists: true on the product object or only delete the whole product object with the packages.
Thanks for the help

How to sustainably organise user schema in mongoose

I have a user which should have the following fields and currently has following schema:
const UserSchema = new Schema(
{
email: {
type: String,
required: true,
index: { unique: true },
lowercase: true,
},
isVerified: { type: Boolean, default: false }, // whether user has confirmed his email
name: { type: String, required: false },
password: { type: String, required: true, minLength: 6 }, // object with next two included?
passwordResetExpires: Date,
passwordResetToken: String,
roles: [{ type: 'String' }], // Array of strings?
username: { type: String, required: false },
token: [{ type: String, required: false }], // used to send verification token via email
},
{ timestamps: true },
);
So yes, what is the world's default standard for organising user schemas. This schema's fields are pretty common, right?

Mongoose model schema referencing not working - Ecommerce model

I am creating multi vendor ecommerce platform, with the following schema.
var user = new Schema(
{
uid: { type: String, index: true, unique: true },
firstName: { type: String, required: true, default: null },
lastName: { type: String, default: null, default: null },
userEmail: { type: String, unique: true, required: true, lowercase: true, },
userProfileImg: { type: String, required: true, default: null },
userDesignation: { type: String, default: null },
userMobile: { type: Number, required: true, default: null },
products: { type: Schema.Types.ObjectId, ref: 'Product' },
}
);
var product = new Schema(
{
sku: { type: String, required: true, unique: true },
title: { type: String, required: true },
category: { type: Array, default: [] },
images: { type: Array, default: [], },
groups: { type: Array, default: [], },
price: { type: Number, default: null, },
unit: { type: String, default: null, },
quantity: { type: Number, default: null, },
description: { type: String, default: null, },
},
);
var AllUser = mongoose.model('User', user, 'AllUsers');
var Allproducts = mongoose.model('Product', product, 'AllProducts');
how can i save multiple products while referring to multiple users? Later i want to populate products based on the users.
Your problem is in referencing the collection. In here when you compile your models
var AllUser = mongoose.model('User', user, 'AllUsers');
var Allproducts = mongoose.model('Product', product, 'AllProducts');
you use Product and for database collection you use AllProducts. That's the problem so...try doing it like this
var Users = mongoose.model('Users', user, 'Users');
var Products = mongoose.model('Products', product, 'Products');
Give it a proper naming convention.
Also there is s typo here in this code.. here I have fixed it
var product = new Schema(
{
sku: { type: String, required: true, unique: true },
title: { type: String, required: true },
category: { type: Array, default: [] },
images: { type: Array, default: [] },
groups: { type: Array, default: [] },
price: { type: Number, default: null },
unit: { type: String, default: null },
quantity: { type: Number, default: null },
description: { type: String, default: null}
}
);
also in your user schema
var user = new Schema(
{
uid: { type: String, index: true, unique: true },
firstName: { type: String, required: true, default: null },
lastName: { type: String, default: null, default: null },
userEmail: { type: String, unique: true, required: true, lowercase: true,
},
userProfileImg: { type: String, required: true, default: null },
userDesignation: { type: String, default: null },
userMobile: { type: Number, required: true, default: null },
products: [{ type: Schema.Types.ObjectId, ref: 'Product' }]
}
);
make products as an array type so that you can store multiple product ids

Updating nested array's field

I have a schema
const RoomSchema = mongoose.Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
},
author: {
type: String,
required: true
},
resource: {
type: String
},
posts: {
type: Array,
default: []
},
url: {
type: String
},
created_at: {
type: String,
required: true
}});
Field 'posts' is another document in my db, defined by the following schema:
const PostSchema = mongoose.Schema({
header: {
type: String,
required: true
},
body: {
type: String,
required: true
},
author: {
username: {type:String, required: true},
_id: {type:String, required:true}
},
room: {
type: String,
required: true
}});
So, I'm trying to create a query that would update fields of certain post inside posts array inside room. I've already tried suggested here, thought without results. I would appreciate any help on the subject
Room.update({ '_id': roomId, 'posts._id': postId },
{ $set: { 'posts.$.header': newHeader, 'posts.$.body': newBody } },
callback);

Categories

Resources