Mongo shell db.model.find() not showing all the documents - javascript

I've defined my schema as follow but when I did db.Titles.find() from mongo shell I didn't get all the documents I have listed. What's wrong did I do ? The author is not showing in the mongo shell. I've tried to add some random document in the list still not showing in the mongo ? Once a model is created, can't it be updated or change? This created a problem when I try to access the list in template. Thanks, in advance.
model :
var mongoose = require("mongoose");
var tSchema = new mongoose.Schema({
title: String,
sypnosis: String,
category: Array,
author: {
username: String,
id: { type: mongoose.Schema.Types.ObjectId, ref: "User" }
},
parts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Part"
}
],
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]
});
var Title = mongoose.model("Title", tSchema);
module.exports = Title;
Mongo shell query :
db.titles.find().pretty()
{
"_id" : ObjectId("5e0d140e7bf04c6a60f97dbd"),
"category" : [ ],
"parts" : [ ],
"comments" : [ ],
"title" : "New Title",
"sypnosis" : "This si a sypnosis",
"__v" : 0
}

Related

Mongoose get object in array of objects

I am using mongoose and I am trying to get users from my mongodb database, Here is what part of my json looks like
"hpCDaKverVWEYukAhAcM8NU6SP73" : {
"admin" : false,
"booksBorrowed" : [ {
"id" : "9780321831552",
"timeStamp" : 1618881802437
}, {
"id" : "9780007204496",
"timeStamp" : 1618881803678
}, {
"id" : "9780316491297",
"timeStamp" : 1618882675513
}, {
"id" : "9780440335160",
"timeStamp" : 1618882676756
}, {
"id" : "9781482287325",
"timeStamp" : 1618887153684
} ],
I am trying to get the books borrowed array
i tried creating a new schema like this
const BorrowedBook = new Schema({
id : {type: String, default: ''},
timeStamp : {type: Number, default: 0},
})
then doing this in mongoose.model
booksBorrowed: [BorrowedBook]
then I do this in server.js
const User = require('./models/user')
app.get('/api/users', function (req, res) {
User.find(function (err, users) {
console.log(users)
})
})
but it just prints this
booksBorrowed: [ [Object], [Object], [Object], [Object], [Object] ],
What am I doing wrong?
You are doing nothing wrong, its just console.log(users) printing this, since it doesnt print nested lvl objects.
You can do console.log(JSON.stringify(users)) or console.dir(users).

Update nested array and populate before that with mongoose

I would like to add a photo into a country in mongoose. But country is an array and photo too. Here is my user schema :
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
firstName: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
birthDate: {
type: Date,
required: true
},
sex: {
type: String,
required: true
},
countries: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Country',
photos: [
{
base64: {
type: String,
required: true
},
title: String,
description: String
}
]
}
],
admin: {
type: Number,
required: true
}
});
Here is what I got as data into mongoDB :
The problem is that I only got the id of countries. And I would like to use another field of the document country. Populate works well when I want to get data, but how to populate and then use the fields to update with mongoDB?
Moreover, I don't know how to update data into nested array, I tried :
User.findOneAndUpdate(
{
"name": "CHARLAT",
"countries": "5d2d847b06f2f94118a36518"
},
{ $push : { "countries.photos" : {
base64: "bla"
} }}
)
As you can see, I use a hand written id for country... I could do a find query before on country but can we use populate here?
And I got this in Postman :
Thank you in advance for your help !
If the type is ObjectId, it can't have a photos field, since it's just an _id. It is a reference to another collection.
Updated answer after comments :
The best thing to do IMO is to create a Photo model which would have the file path and the country's _id. The User model would only store a list of Photos [_id].
UserSchema :
{
.....
photos : [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Photo'
}],
.....
}
PhotoSchema :
{
country : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Country'
},
path : String
}
Then, query your Users this way, by populating the photos, and inside each photo, populating the countries :
UserModel
.find(conditions)
.populate({
path: 'photos',
model: 'Photo'
populate: {
path: 'country',
model: 'Country'
}
})
.lean() // Faster and lighter for read-only, simply returns an object
So you should get a User object like this :
{
.....
name : "John",
photos : [{
country : {
name : "Country 1",
code : "C1" // or whatever field you have in your Country model
},
path: "path/to/photo1.jpg"
},
{
country : {
name : "Country 2",
code : "C2"
},
path: "path/to/photo2.jpg"
}]
.....
}

How to prevent the plugin for nested schemas

I have a mongoose schema for categories
import mongoose from 'mongoose';
import { imageScheme } from './data.schemas';
mongoose.plugin(require('mongoose-delete'));
mongoose.plugin(require('mongoose-timestamp'));
const Schema = mongoose.Schema;
const catScheme = new Schema({
title: {
type: String
},
subTitle: {
type: String
},
description: {
type: String
},
images: [imageScheme],
icon: {
type: String
},
deleteAt: {
type: Date,
default: null
}
});
const Category = mongoose.model('Category',catScheme);
export default Category;
my image schema is located in another file
const imageScheme = new Schema({
imageCaption : {
type: String
},
imageFileName: {
type: String,
required: true
},
imagePath: {
type: String,
required: true
}
});
and when I am using the model for creating new category its adding the timestamp and deleted for my images array which means its loading the plugins ( mongoose-delete , mongoose-timestamp ) into the sub schema
HOW TO AVOID THAT ?
that is the result
{
"_id" : ObjectId("5d5a822f20179023e008f10c"),
"deleteAt" : null,
"deleted" : false,
"title" : "Eyes and Ears",
"description" : "here you will find all ppe to keep your eye 6 sharp",
"icon" : "glass.svg",
"images" : [
{
"_id" : ObjectId("5d5a822f20179023e008f10e"),
"deleted" : false,
"imageCaption" : "Eyes and Ears",
"imageFileName" : "67acca17-3fc8-416c-bc00-8273770b2115.jpeg",
"imagePath" : "resources/images/67acca17-3fc8-416c-bc00-8273770b2115.jpeg",
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z")
},
{
"_id" : ObjectId("5d5a822f20179023e008f10d"),
"deleted" : false,
"imageCaption" : "Eyes and Ears",
"imageFileName" : "9f1c5b1f-c1be-48f2-a9bc-8294930fd4c9.jpeg",
"imagePath" : "resources/images/9f1c5b1f-c1be-48f2-a9bc-8294930fd4c9.jpeg",
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z")
}
],
"updatedAt" : ISODate("2019-08-19T11:04:15.756Z"),
"createdAt" : ISODate("2019-08-19T11:04:15.756Z"),
"__v" : 0
}
It looks like you are plugging the mongoose-delete and mongoose-timestamp in the whole database.
Have you tried the example provided in the plugin pages?
catScheme.plugin(mongoose-timestamp)
catScheme.plugin(mongoose-delete)

Mongoose deep populate results in [Object] at 2nd level

After spent 1 day trying to get things done, I think it's time to ask for help.
I want to populate 2 levels of a document.
I tried with populate() but it seems to work only for first level, not deep populate! I read a lot at SO and I know it should work but I think I'm missing something really stupid...
Please let me know where I'm making mistakes.
Here are the relevant code.
Schemas
var compositionSchema = new Schema({
name: {
type: String,
required: true
},
contributions: [{
type: Schema.Types.ObjectId,
ref: 'Contribution'
}]
});
mongoose.model('Composition', compositionSchema);
var contributionSchema = new Schema({
name: {
type: String,
required: true
},
media: {
type: Schema.Types.ObjectId,
ref: 'Media'
}
});
mongoose.model('Contribution', contributionSchema);
var mediaSchema = new Schema({
name: {
type: String,
required: true
}
});
mongoose.model('Media', mediaSchema);
Actual documents saved in MongoDB
compositions:
{
"_id" : ObjectId("59e5db4595fe650a71fb0e07"),
"name" : "Test Pop 7",
"contributions" : [
ObjectId("59e5db4595fe650a71fb0e05")
]
}
contributions:
{
"_id" : ObjectId("59e5db4595fe650a71fb0e05"),
"name" : "Honda",
"media" : ObjectId("59e4ac5dacacd709eac2c856")
}
media:
{
"_id" : ObjectId("59e4ac5dacacd709eac2c856"),
"name" : "Logo_big.png",
"width" : 662,
"height" : 540
}
My tries (= the wrong code?)
In Node JS, when I do this (as per documentation):
Composition.findOne({ name: "Test Pop 7" })
.populate({
path: 'contributions',
model: 'Contribution',
populate: {
path: 'media',
model: 'Media',
}
})
.exec((error, doc) => {
if (error) { console.log(error); }
else {
console.log(doc);
}
});
prints out this, without actually populate the media field:
{ _id: 59e5db4595fe650a71fb0e07,
name: 'Test Pop 7',
contributions:
[ { _id: 59e5db4595fe650a71fb0e05,
name: 'Honda',
media: [Object] } ]
}
It works, keeping in mind the key-word in your question: prints. Printed, with console.log(), it just shows you the type (checked with typeof) of the document included in an array for some (2nd) level of nesting. If you do:
console.log(doc.contributions[0].media[0])
you will see your populated media document.

checking if an array contains a post id in a mongodb document

Let's say I want to look up a user by their _id and check if the "liked" value (array) contains a certain post _id. How do I query the db for this action? Is it okay to just store these _id's in an array or does mongodb convention prefer something else to store as a reference to other documents?
So I just want to check if the user has the post _id in the "liked" array.
var users = new mongoose.Schema({
name : {type: String, unique : true, required : true, dropDups: true},
password : {type: String, required : true}, //hash
liked : [String],
created : {type: Date, default: Date.now}
});
Here is how I think this might look:
function checkIfLiked() {
let uname = "Jim";
let postId = "abc";
//check if $USER has `postId` in $LIKED
user.findOne({$USER: uname},{$LIKED: {$in: postId} }, function(err, results) {
//do something after check
});
}
For the user data
{ "_id" : ObjectId("56effca6e668e15e2eaa6dfe"), "liked" : [ "11", "23", "4" ], "name" : "aa" }
{ "_id" : ObjectId("56effcb1e668e15e2eaa6dff"), "liked" : [ "1", "2", "3" ], "name" : "bb" }
To check the user name aa with 4 in liked array
> db.user.find({liked: '4', name: 'aa'})
{ "_id" : ObjectId("56effca6e668e15e2eaa6dfe"), "liked" : [ "11", "23", "4" ], "name" : "aa" }
but
> db.user.find({liked: '2', name: 'aa'})
No matched result.
Is it okay to just store these _id's in an array or does mongodb convention prefer something else to store as a reference to other documents?
Mongoose population could do that, you can define the user schema as below
var users = new mongoose.Schema({
name : {type: String, unique : true, required : true, dropDups: true},
password : {type: String, required : true}, //hash
liked : [{ type: Schema.Types.ObjectId, ref: 'User' }],
created : {type: Date, default: Date.now}
});
var User = mongoose.model('User', users);

Categories