Compare Array with Collection-Array containing Objects - node.js

This is my collection schema:
var objectSchema = new Schema({
members: [{
user_id: ObjectId,
settings: {
type: Boolean
}
}],
title: String
});
And now I'm trying to search for objects with specific members (identified by their "user_id", for example ["asdf123lkd", "asdf1223"]).
Is there any way to search for these objects?
Thanks!

You can try this:
objectModel.find({ 'members.user_id' : {'$in' : ['asdf123lkd', 'asdf1223']} }, function(err, data) {
console.log(err,data);
})

Related

How to populate data from nested object in mongoose

I am having schema like below:
const commentSchema = new Schema({
name: String,
surname: String,
email: String,
positions: [
{ detail: [{
type: Schema.Types.ObjectId,
ref: 'Position'
}],
progress: { type: String }, // keep track of the status
comment: { type: String } // keep track of internal notes
}],
});
Field detail contains array of mongo ids.
I am trying with below code but not getting the populated data:
const requirementsData = await Requirement.find({})
.populate({
path: "positions.detail",
model: Position,
})
.exec(function(err, docs) {
if(err){
console.log("err====", err)
}else{
res.render('candidates/show', {candidate: docs})
}
});
if I understand your problem you can do this
.populate({
path:'position',
populate:{path:'details'}
})

How to find documents inside ref object without an id?

I have two documents in mongodb:
export const Category = mongoose.model('Category', new mongoose.Schema({
name: { type: String },
}));
export const SubCategory = mongoose.model('SubCategory', new mongoose.Schema({
name: { type: String },
category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
}));
How to find All SubCategory that match Category by name?
I have try a lot of ways but I always getting null or error...
var name = '...';
SubCategory.find({ category: { name } });
SubCategory.find({ category: { name } }).populate('category');
You can use aggregation for the same. Please read this documentation https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
Note:- This answer is based on your collection and data you have entered. this is not perfect but this will help best to find the logic from this answer. :-)
//collection 1 schema
const collection1Schema = new Schema({
user_id: {
type: String,
required: true
},
status: {
type: String
}
});
mongoose.model('Collection1', collection1Schema);
//collection 2 schema
const collection2Schema = new Schema({
user_id: {
type: Schema.Types.ObjectId,
ref: 'user_id'
},
item: {
type: String
}
});
mongoose.model('Collection2', collection2Schema);
//find data from collection2
Collection2.find()
.populate('user_id')
.exec(function(err, foundDocuments) {
if (error) {
console.error(err);
} else {
console.log(foundDocuments);
}
});
For more info:- Mongoose populate

Mongoose populating array inside nested schema

This is my schema:
var userSchema = {
folders : [ folderSchema ],
...
}
var folderSchema = new mongoose.Schema({
itemlist : [{ type: String, ref: 'Item', required: true }],
foldername : { type: String},
...
});
// Item model
var itemSchema = {
name: { type: String },
...
}
I would like to populate itemlist (entire array) inside of each folderSchema, is this possible?
What I've tried so far but doesn't work:
userModel.findOne({ _id: userId }, null, callback).populate({
path: 'folders.$.itemlist',
select: 'name'
});
This post and this post are similar but they store the folder models and have a ref instead of nested document.
Bonus: is it possible to select only some folders by foldername to populate their itemlist?
I think you are looking for "deep population", see the population section "Populating across multiple levels"
rewrite your populate to:
userModel.findOne({ _id: userId }, null, callback).populate({
path: 'folders',
populate: { path : 'itemlist'}
});
The easiest solution is to actually retrieve the nested folder and perform a find manually. Then simply call find({_id: {$in : folder}}); to find all elements of array.

Returning only first element of a sub array with $elemMatch

I'm using node and mongoose, and have a schema that looks like this:
var SubscriberSchema = new Schema({
'user': [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
'level': { type: String, enum: [ 'owner', 'sub', 'commenter', 'poster' ] }
'dateAdded': { type: Date, default: Date.now }
});
// Group Schema
var GroupSchema = new Schema({
'groupOwner': [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
'groupName': String,
'subscribers': [SubscriberSchema],
});
I would like to query the group to find all groups where a user (stored in req.user._id via token authentication) is a subscriber (i.e. their _id is in the subscribers array), and only return the single subscribers array element with their _id.
I've read the Mongo documentation on $elemMatch as this seems to be what I need, and built the query below. This returns the information I want, but returns all elements of the subscribers array. How can I return only the single element of the subscribers array that matches my req.user._id?
Current query, returns all elements of subscribers:
Group
.find( { "subscribers.user": req.user._id}, { subscribers: { $elemMatch: { user: req.user._id }}} )
.sort('groupName')
.populate('groupOwner', 'email firstName lastName')
.populate('subscribers.user', 'email firstName lastName')
.exec(function(err, data) {
if (err) {
logger.error('Unable to retrieve groups for user: ' + err.message);
res.status(500)
} else {
res.json(data);
}
});
This returns the following for subscribers (via util.inspect(data[0].subscribers)):
Subscribers
[{
user:
[ { _id: 1234,
email: 'me#here.com',
firstName: 'Testy',
lastName: 'Testelson' } ] }
user:
[ { _id: 5678,
email: 'you#there.com',
firstName: 'Biggy',
lastName: 'Smalls' } ] }]
Based on the $elemMatch docs, I would assume I would only see user 1234 since that's the record that matches req.user._id. What am I doing wrong here?
Thanks!
In your projection parameter, use the dollar operator:
{"user.$": 1}
This will return a Group with only a single object in its 'subscribers' array.

Mongoose Relationship Populate Doesn't Return results

var SecuritySchema = new Mongoose.Schema({
_bids: [{
type: Mongoose.Schema.Types.ObjectId,
ref: 'BuyOrder'
}],
_asks: [{
type: Mongoose.Schema.Types.ObjectId,
ref: 'SellOrder'
}]
});
var OrdersSchema = new Mongoose.Schema({
_security: {
type: Mongoose.Schema.Types.ObjectId,
ref: 'Security'
},
price: {
type: Number,
required: true
},
quantity: {
type: Number,
required: true
}
});
// declare seat covers here too
var models = {
Security: Mongoose.model('Security', SecuritySchema),
BuyOrder: Mongoose.model('BuyOrder', OrdersSchema),
SellOrder: Mongoose.model('SellOrder', OrdersSchema)
};
return models;
And than when I save a new BuyOrder for example:
// I put the 'id' of the security: order.__security = security._id on the client-side
var order = new models.BuyOrder(req.body.order);
order.save(function(err) {
if (err) return console.log(err);
});
And attempt to re-retrieve the associated security:
models.Security.findById(req.params.id).populate({
path: '_bids'
}).exec(function(err, security) {
// the '_bids' array is empty.
});
I think this is some sort of naming issue, but I'm not sure, I've seen examples here and on the moongoose website that use Number as the Id type: http://mongoosejs.com/docs/populate.html
The ref field should use the singular model name
Also, just do:
models.Security.findById(req.params.id).populate('_bids').exec(...
My main suspicion given your snippet at the moment is your req.body.order has _security as a string instead of an array containing a string.
Also, you don't need an id property. Mongodb itself will automatically do the _id as a real BSON ObjectId, and mongoose will add id as a string representation of the same value, so don't worry about that.
While I don't understand your schema (and the circular nature of it?), this code works:
var order = new models.BuyOrder({ price: 100, quantity: 5});
order.save(function(err, orderDoc) {
var security = new models.Security();
security._bids.push(orderDoc);
security.save(function(err, doc) {
models.Security.findById({ _id: doc._id })
.populate("_bids").exec(function(err, security) {
console.log(security);
});
});
});
It:
creates a BuyOrder
saves it
creates a Security
adds to the array of _bids the new orderDoc's _id
saves it
searches for the match and populates
Note that there's not an automatic method for adding the document to the array of _bids, so I've done that manually.
Results:
{ _id: 5224e73af7c90a2017000002,
__v: 0,
_asks: [],
_bids: [ { price: 100,
quantity: 5,
_id: 5224e72ef7c90a2017000001, __v: 0 } ] }

Resources