mongoDB querying nested documents within a nested document - node.js

I'm having problems accessing user.info.name.familyName in a query. I'm newish to database design and queries and I don't know if its possible.
So here is the schema I have. Perhaps it might need to be redesigned for what I'm trying to do to work.
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true,
required: true,
unique: true
},
password: {
type: String,
required: true
},
email: {
type: String,
required: true,
lowercase: true
},
emailVerified: {
type: Boolean,
default: false
},
info: {
name: {
givenName: String,
familyName: String,
},
address: {
street: String,
city: String,
state: String,
zipCode: String
},
primaryPhone: String,
cellPhone: String,
website: String,
licenseNumber: String,
title: String,
company: String
},
avatar: {
type: String,
default: '/images/avatar/default/contacts-128.png'
},
friends: [{ type: ObjectId, ref: User }],
friendRequests: [{ type: ObjectId, ref: User }]
});
I have a search function that currently searches by username or email and works fine, but I'd like it to also search by the users givenName or familyName. Here is the search function...
module.exports.search = function(searchValue, callback) {
var searchValue = new RegExp(`^${searchValue}`, 'i');
var query = {
$or: [
{username: searchValue},
{email: searchValue}
// {givenName condition here...}
]
}
User.find(query, callback).limit(10);
}
I tried this... and it didn't work
{info.name.givenName: searchValue}
I tried a few other nonsensical things but they also failed...
So to summarize my question, how would I either restructure the schema or query to be able to check the searchValue against user.info.name.givenName?

This way:
{'info.name.givenName': searchValue}
notice the quotes.
You were close :)

Related

Adding subcollection into mongodb to an existing document

Hey when i was using firebase it was kind of easy to update or add a subcollection , but its confusing in mongodb ! i see people adding arrays instead of subcollection but what if i want to add an element to that existing array ! how can it be done , or how to add something like subcollection !
here is my example !
Model :
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
passwordHash: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
default: false,
},
street: {
type: String,
default: "",
},
apartment: {
type: String,
default: "",
},
zip: {
type: String,
default: "",
},
city: {
type: String,
default: "",
},
country: {
type: String,
default: "",
},
});
exports.User = mongoose.model("User", userSchema);
I want to add a notification collection or document to this User model whenever he recieves one ? i want the notifications to be a collection with documents referring the each notification ! but i didn't know how to do it !

I want to join two schemas into one schema in nodejs mongodb

I want to join two schemas into one because they both have almost same attributes and i want to use it for PostSchema that a user and also an owner can create and show their posts but i dont know how to achieve it
for example :
UserSchema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User",
},
});
OwnerSchema
const OwnerSchema = new mongoose.Schema({
name: String,
gender: String,
email: String,
password: String,
role: {
type: String,
default: 'Owner'
},
restaurant: RestaurantSchema
})
PostSchema
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
body: {
type: String,
required: true,
},
photo: {
type: String,
required: true,
},
postedBy: {
type: ObjectId,
ref: *Combined user and owner*,
},
comments: [CommentSchema],
}, { timestamps: true });
Get rid of your OwnerSchema - and modify your UserSchema to something like the below:
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User", //could be Owner when applicable
},
restaurant: RestaurantSchema, //could be null when role=User
});

Mongoose populate how to join populate sub document to another collection

Organizers, Products collections, I need to join products table with posted user id and organizers collections and purchased userid with users and organizers again. I can join products with users but not able to join users with organizer.
Products.find({})
.populate({
path: 'intresteduserIds.userId',
// Get friends of friends - populate the 'friends' array for every friend
populate: { path: 'intresteduserIds.user_organizationid' } /* How to join with organizer collection which have organizer id*/
})
.populate('product_postedby');
Products schema:
const ProductsObj = new Schema({
product_title: String,
product_category: String,
product_startDate: Date,
product_startTime: String,
product_endDate: Date,
product_endTime: String,
product_isPrivateEvent: Boolean,
product_desc: String,
product_postedby: { type: mongoose.Schema.ObjectId, ref: 'User' },
intresteduserIds: [
{
userId: {
type: mongoose.Schema.ObjectId,
ref: 'User',
requested: false
},
name: String,
email: String,
mobilenumber: String,
notes: String,
requirestedDate: Date,
status: String,
eventsList: [
{
id: mongoose.Schema.ObjectId,
name: String
}
],
intrestedType: String
}
]
});
Users schema which contain organizer id:
const usersSchema = new Schema({
user_organizationid: {
type: mongoose.SchemaTypes.ObjectId,
required: false,
index: true,
ref: 'Oranizations'
},
user_firstname: String,
user_lastname: String,
user_username: String,
user_mobilenumber: String,
user_mobilenumber_code: String,
user_email: String,
user_role: {
type: mongoose.SchemaTypes.ObjectId,
required: false,
index: true
}
});
Organizer schema:
const organizerSchema = new Schema({
org_name: String,
org_type: String, // organizer,ground , ecommerce seller,
org_category: String, // corporate company,supplier
org_logo: String,
org_address_id: { type: mongoose.Schema.ObjectId, required: false },
org_stack_exchange_id: String,
org_created_dated: Date,
org_updated_date: Date,
org_activte_status: Boolean,
user_hashcode: String
});
So eventually I need:
{
product:'product info',
posted_userid:{
posted_userinfo:'',
organizerInfo:'join with user if there this information'
},
intrestedusers:{
userid:{
userinfo:'',
organizerInfo:'join with user if there this information'
}
}
}
How can I get solution over here?
Inner path must be user_organizationid instead of intresteduserIds.user_organizationid
Products.find({})
.populate({
path: 'intresteduserIds.userId',
populate: {path: 'user_organizationid' }
})
.populate('product_postedby');

Swap an object in a Mongoose array with another object in the array of another document

Consider this schema:
let userSchema = new Schema({
email: { type: String, required: true },
password: { type: String, required: true },
books: [{
owner: String,
cover: String,
title: String,
link: String,
requestsReceived: { requestingUser: String, bookOffered: String },
requestsSent: { toUser: String, bookWanted: String },
beingRequested: { type: Boolean, default: false },
beingSent: { type: Boolean, default: false }
}],
ip: String
});
the books array contains objects which hold a variety of information. How can I take a certain book object from array of document 1 and swap it with array of document 2 preferably with the least amount of queries to the DB. (i.e. between two different user documents)
I know this is a bit difficult. Much appreciated.

Mongoose query through the element inside the array

I have a mongoose model:
let schema = new Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String
},
username: {
type: String,
unique: true
},
confirmed: {
type: Boolean
},
payload: [{
type: {
token: blablabla,
type: blablabla
}
}]
});
And i want find user by payload.token. How can I do that? I tried $elemMatch, but it does not work.
You can do
.find({'payload.type.token': token})
If payload is an array of objects and you want to find users by token value , below query should work :
db.users.find({payload: {$elemMatch: {'type.token':'blablabla'}}});

Resources