mongodb relations find one with all their related - mongodb

I know how to get data with their related
var UserSchema = new Schema({
username: String
});
var PostSchema = new Schema({
title: String,
author: {type: Schema.Types.ObjectId, ref: 'User'}
});
...
Post.findOne({_id: id})
.populate('author')
.exec(function(error, result) {
// do stuff
})
but how to do the opposite?
I mean when I want a user, with all their posts with single query?

Try adding a filter step after the query returns that manually filters out documents which don't have any posts that matched the populate criteria:
var username = "foo";
Post.find()
.populate('author', null, {username: username})
.sort({'_id': 1})
.exec(function (err, posts) {
posts = posts.filter(function(post){
return post.author.length;
});
res.send(posts);
});

Related

mongoose select query with count from other collections

I am working with node(express) with mongoose and I have two collections,
Users
Comments
I added the sample Schema(added few fields only)
const UserSchema = mongoose.Schema({
name: String,
email: String,
});
const CommentsSchema = mongoose.Schema({
comments: String,
user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
text: String,
});
So I trying to fetch the users list and no of comments count based on user..
Expecting output like below:
data = [
{
name: 'abcd',
email: 'aa#test.com',
commentsCount: 5
},
{
name: 'xxx',
email: 'xx#test.com',
commentsCount: 3
}
]
I am not sure how to get the results, because we don;t have ref in user table..
userModel.find({}).exec((err, users) => {
if (err) {
res.send(err);
return;
}
users.forEach(function(user){
commentsModel.countDocuments({user_id: users._id}).exec((err, count) => {
if(!err){
user.commentsCount = count;
}
})
});
console.log('users', users)
});
Can you anyone please help to fix, I needs to list out the users and count of comments

findOneAndUpdate doesn't create ObjectId

I need to make a patch request to update only one (or several) field(s) at the same time.
I've got a big object which is my document, and inside nested array of objects.
For example, for my car array, this is the schema :
const carSchema = new Schema({
owner: [{value: {type: String}, label: {type: String}}],
carPlate: {type: String},
carColor: {type: String},
carBrand: {type: String},
carStatus: {type: String}
});
const myObject = new Schema({
...
cars: [carSchema]
...
});
When I send my changes, I do it this way :
let dynamicVar = 'cars.'+i+'.'+myfield;
this.props.updateGeneral({_id: this.props.general._id, [dynamicVar ]: [myfield.value]});
I'm on redux, so my action looks like :
export function updateGeneral(data) {
let _id = data._id;
delete data._id;
return {
type: 'UPDATE_GENERAL',
payload: client.patch(`${url}/${_id}`, data)
}
}
And my PATCH request is like :
router.patch('/url/:id', async (req, res, next) => {
myObject.findOneAndUpdate({_id: req.params.id}, {$set: req.body }, {upsert: true, new: true}, function (err, objectReturn) {
if (err) return next(err);
cn = cn.substr(0, cn.indexOf(' {'));
res.json(objectReturn);
});
});
My BIG issue is that my field is update or inserted, but if it's inserted and it creates a new array it won't create the objectId linked. It won't even create the array of object,just an object with a property.
How can I make mongoose initiates ObjectId??
Per the reply to this SO post it looks like you cannot update object IDs. When doing so, you are effectively "deleting" the object and creating a new one.

unable to populate documents using mongoose populate()

I am making an application in express using mongoose. I have a collection called users in which there is a filed called _subscriptions, which is an array of objects and each object contains a field named field which is an ObjectId for the documents of fields (this is another collection in my db).
I want to make such an API which after getting id parameter returns me a user form users collection with field attribute populated instead of its id in value of the field field. For this I am using populate method but it is not working.
This is screenshot showing users collection:
This is screenshot showing fields collection:
This is schema for field (File name Field.js):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var FieldSchema = new Schema(
{
_id: Schema.Types.ObjectId,
name: String,
price: Number,
_categories: [{
type: Schema.ObjectId,
}],
}
);
module.exports = mongoose.model('Field', FieldSchema);`
This is schema and model for users
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
_id: Schema.Types.ObjectId,
salt: String,
provider: String,
name: String,
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
_subscriptions: [{
field: {
type: mongoose.Schema.ObjectId,
ref: 'Field',
},
status: String,
dateSubscribed: Date,
payments: [{}]
}],
role: String,
});
module.exports = mongoose.model('User', UserSchema);
This is code for user router
var Field = require('../model/Field');
var express = require('express');
var router = express.Router();
var User = require('../model/User');
router.get('/',function(req, res, next) {
User.find({}, function(err, result) {
if (err) {
console.log(err);
res.send('something wrong');
}
res.status(200).send(result);
}).populate( '_subscriptions.field').exec(function (err, story) {
if (err) return handleError(err);
console.log('Here!!!!!');
});
});
router.get('/findById/:id',function(req, res, next) {
var id = req.params.id;
User.findById(id, function(err, doc) {
if (err) {
console.error('error, no entry found');
}
res.status(200).send(doc);
}).populate('field').exec(function (err, story) {
if (err) return handleError(err);
console.log('Here!!!!!');
});
});
router.get('/getSubscriptions/:id',function(req, res, next) {
var id = req.params.id;
User.findById(id, function(err, doc) {
if (err) {
console.error('error, no entry found');
}
var type = typeof(doc);
res.status(200).send(doc);
})
});
module.exports = router;
This is where I have called app.use method:
And this is response I am getting using postman
I am looking forward for someones' assistance in resolving this issue
as i am unable to identify my mistake. Your help in this regard will be highly appreciated.
Thanking in advance
What I have understood is, In the user collection, there is _subscriptions and in _subscriptions, there is field. If this is your schema, then you should pass "_subscriptions.field" as a parameter to the populate function not "field" as you have passed currently.
So, your code for user's sub route, /findById/:id, must be like this:
router.get('/findById/:id',function(req, res, next) {
var id = req.params.id;
User.findById(id, function(err, doc) {
if (err) {
console.error('error, no entry found');
}
res.status(200).send(doc);
}).populate('_subscriptions.field').exec(function (err, story) {
if (err) return handleError(err);
console.log('Here!!!!!');
});
});

`_id` in where clause

I face an issue trying to access _id in a query.where.
My schema:
var testSchema = new Schema({
test2id: [{ type: Schema.Types.ObjectId, ref: 'Test2' }],
test3id: [{ type: Schema.Types.ObjectId, ref: 'Test3' }]
});
var test2Schema = new Schema({
name: String
});
var test3Schema = new Schema({
name: String
});
My query:
testSchema.statics.findByid = function (id, callback) {
var query = this.findOne();
Test2.findOne({'name': name}, function (error, t2) {
query.where({
test2id: _id,
}).exec(callback);
});
return query
};
_id is undefined, I try also this._id but the query return null.
I just want to get all documents from testSchema with test2id = _id of the testSchema document.
Any idea to fix that and access to _id from a query.where clause?
I finally resolve it by passing it in parameter.
var test = new Test();
test.findByid(test._id, req.params.id, function(err, res) {
...
});

Sort Nested document in MongooseJS

This is my schema:
var Review = new Schema({
user: {type: ObjectId, ref:'User'},
lastModified: {type: Date, default: Date.now }
});
var Subject = new Schema({
name: String,
review: [Review],
...
});
The query will return all the subjects with review from a user.
{'review.user': id}
Is it possible to sort the result based on review.lastModified?
Subject.find({'review.user': id}).select('name').sort('???').exec( function(err, subjects){
if (err) return res.json(error);
console.log('subject', subjects);
});
You cannot sort within a document using MongoDB. Sorting within the document must be done at the application level.