Mongoose query through the element inside the array - node.js

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'}}});

Related

Mongoose Query is not fetching match data from multiple table

I am using nodejs,mongodb and mongoose. This query is not fetching match data from user and order table. I have read mongoose docs and alot of other articeles. It's according to it but doesn't fetch match data from tables.
Query code:
const data = await order
.find({ admin_id: req.params.id })
.populate("orderRelate");
console.log(data);
My user and order schema code is:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
mobile_no: { type: Number, required: true },
profilePic: { type: String, defaut: "" },
owner: { type: Boolean, defaut: false },
},
{ timestamps: true }
);
const orderSchema = new mongoose.Schema(
{
customer_id: { type: String, required: true },
admin_id: { type: String, required: true },
order_type: { type: String, defaut: "normal" },
order_status: { type: String, required: true },
order_price: { type: Number, required: true },
order_address: { type: String, required: true },
order_pickDate: { type: String, required: true },
order_pickTime: { type: String, required: true },
orderRelate: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
},
{ timestamps: true }
);
module.exports = mongoose.model("User", UserSchema);
module.exports = mongoose.model("Order", orderSchema);
Please let me know if anyone know why I am facing this issue.
Thanks
Please try with findById maybe it's work
i don't know how you wrote your middleware function but..
await Order.find({orderRelate: req.user.id})

How to use virtual on a nested field in mongoose

I am using mongoose in node.js. I have the following Schema.
const CustomerSchema = new mongoose.Schema({
...
email: {
type: String,
required: true,
lowercase: true,
trim: true
},
addresses: [
{
addressType: {
type: String,
enum: [ 'personal', 'shipping', 'billing' ]
},
street: {
type: String,
required: true,
trim: true
},
streetNumber: {
type: String,
trim: true
},
floor: {
type: String,
trim: true
},
apartament: {
type: String,
trim: true
},
cp: {
type: String,
required: true,
trim: true
},
district: {
type: String,
trim: true
},
city: {
type: mongoose.Schema.ObjectId,
ref: 'City',
required: true
}
}
]
});
I want to use "virtuals" to "add" a new field in every object in the array addresses?
How I can do this using virtuals? Is it possible?
I can achieve the same result using, but I would like to use virtuals.
const customerDB = await Customer.findById(idCustomer).lean()
customerDB.addresses = customerDB.addresses.map((address) => ({
...address,
addressDesc: mapTypeAddressDescription(address.addressType)
}));
Many Thanks!
As the name suggests virtuals are not added to the MongoDB documents. They are used for computed properties on documents.
Suppose you have a User model. Every user has an email, but you also want the email's domain. For example, the domain portion of 'test#gmail.com' is 'gmail.com'.
Below is one way to implement the domain property using a virtual. You define virtuals on a schema using the Schema#virtual() function.
const userSchema = mongoose.Schema({
email: String
});
// Create a virtual property `domain` that's computed from `email`.
userSchema.virtual('domain').get(function() {
return this.email.slice(this.email.indexOf('#') + 1);
});
const User = mongoose.model('User', userSchema);
let doc = await User.create({ email: 'test#gmail.com' });
// `domain` is now a property on User documents.
doc.domain; // 'gmail.com'
You should check the documentation for more details.
You can do something like this:
CustomerSchema.path('addresses').schema.virtual('fullAddr').get(function() {
return 'foo'
})
Also, it is useful to check this answer on stackoverflow if the above one doesn't work.

How to search in multiple collections in MongoDB using Mongoose

I have two collections User and UserType :-
var User = new mongoose.Schema({
username: {
type: String,
required: true,
},
userType: {
type: ObjectId,
ref: "UserType",
required: true,
},
});
var UserTypeSchema = new mongoose.Schema(
{
type: String,
type_code: Number,
type_description: String,
},
{ timestamps: true }
);
I want to search user based on username and typecode which is in UserType Collection.
I tried this code: -
User.findOne({
username: mobileNumber,
userType: { type_code: userTypeCode },
})
.populate("userType");
please correct this query.
you must to filter out populate results, with match option
In your case answer would be::
User.findOne({
username: mobileNumber,
}).populate({
path: "userType",
match: { type_code: userTypeCode },
});
you can check the documentation

Mongoose is not returning all fields in the document using a simple find()

I have the following Schema:
let User = new Schema({
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
firstName: {
type: String,
required: false
},
lastName: {
type: String,
required: false
},
templates: {
type: Schema.Types.ObjectId,
ref: 'TemplateInstance',
required: false
}
},{
collection: 'users',
timestamps: true
});
And the following Mongoose code:
exports.getUsers = (req, res) => {
User.find((err, users) => {
if(err)
return res.status(400).json( { 'users_get_all': 'failure', 'err': err } );
return res.status(200).json( { 'users_get_all': 'success', 'users': users } );
});
};
Initially, each user Document does not have anything in the 'templates' field because after the user creates their account, that's when they get to attach templates to it. I have manually added some Template ObjectIDs to the 'templates' field of some users but when I run the getUsers() function, the user documents are returned but with no 'templates' field:
{"users_get_all":"success","users":[{"_id":"5b39f9da294d041b58f97cb3","email":"testemail#email.com","password":"password","firstName":"firstName","lastName":"lastName","createdAt":"2018-07-02T10:09:30.400Z","updatedAt":"2018-07-02T10:21:34.579Z","__v":0},{"_id":"5b39ff5723d93c17bc00eabf","email":"testemail2#email.com","password":"password","firstName":"firstName2","lastName":"lastName2","createdAt":"2018-07-02T10:32:55.308Z","updatedAt":"2018-07-02T10:32:55.308Z","__v":0}]}
If I look at the MongoDB in something like Studio 3T, the templates array definitely has ObjectIDs in it that refer to Templates in the Template collection.
Any idea why the 'templates' field is not being returned?
Update your schema as follows:
let User = new Schema({
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
firstName: {
type: String,
required: false
},
lastName: {
type: String,
required: false
},
templates: [{
type: Schema.Types.ObjectId,
ref: 'TemplateInstance',
required: false
}]
},{
collection: 'users',
timestamps: true
});
As in database, you have templates in the array and you were declaring it an object in the schema.

mongoDB querying nested documents within a nested document

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 :)

Resources