Find user dynamically - node.js

** I want to create a function that accepts any data like id, email, etc., and finds the user based on the input passed to it. **
ex:
const user = async(input)=>{
const result = data.findOne({input}); //whatever the input I passed I want the user
return result;
}
should I Pass the key with input like (input, key)??
so I need one common function to find the user data dynamically

Assuming you know ahead of time what fields the data might be found in, use $or to check them all:
data.findOne({$or: [
{id: input},
{email: input},
{username: input}
]})

Related

Given a mongodb model's array I want to find records in which that array has the most matches using mongoose

I have a mongoose schema as such:
const userSchema = new mongoose.Schema({
keywords: [{ "type": String, "enum": ["yup", "nope"] }],
})
Here, I have one user with a set of keywords and I want to find the records in my database which have the most similar set of keywords to this particular user.
For example, If a user has ["yup" "nope"] as their keywords, I want to find all records of users who have "yup" or "nope" or both in their keywords array. This is just an example and in reality, the users will have a whole lot more keywords to choose from.
How can I do this using mongoose?
I was thinking about one-hot-encoding the values in the array and the records with the most matching 1s can be added to another table "Most similar values table or something" that maintains this list for every user with the user as the foreign key. But I haven't been able to come up with an efficient and/or working algorithm for this yet.
In my opinion the best aproach is regular expresion. I write you one example function how to search and filter data in MongoDB using mongoose. For example lets search customers by lastName example for starts, ends, contains string "yup". Be aware searching with regex is case sensitive default. If you add "i" after regex it will be case insensitive.
async function getCustomers() {
const customers = await Customer
//case search lastName whitch starts with "yup" - case sensitive
.find({lastName: /^yup/})
//or case search lastName whitch ends with "yup" - case insensitive
.find({lastName: /yup$/i })
//or case search lastName whitch contains "yup" in any part
.find({lastName: /.*yup.*/ })
.limit(20) //get top 20 results
.sort({lastName: 1}) // sort by lastName
console.log(customers)}
//searching in array
const customerList = ['Smith', 'Jackson'];
async function getCustomers(arr) {
return await Customer
.find({lastName: {$in: arr}})
.limit(20) //get top 20 results
.sort({lastName: 1}) // sort by lastName
}
getCustomers(customerList);
for more info chceck documentations:
https://docs.mongodb.com/manual/reference/operator/query/regex/

Could not find the right value using the MongoDB aggregate function

I need to fetch value as per some user input using MongoDB aggregate function but in my case, I could not return the right value. Here is my code:
var cname=req.body.cname;
var id=req.body.id;
Company.collection.aggregate([
{ $match:{$and:[{cname:cname},{_id:{$ne:id}}]}}
])
I need to fetch those value by comparing the cname value and _id is not equals to the given id. But In my case, the user input id value is fetching where I need other the user input id documents.
You need to change the query as mentioned below:
Company.collection.aggregate([
{ $match:{$and:[{cname:cname},{$ne:{_id:id}}]}}
]);
See if it helps!
You can try below code.
const ObjectId = require('mongodb').ObjectId;
Company.collection.aggregate([
{$match : {$and: [{cname:cname},{$ne:{'_id':ObjectId(id)}}]}}
]);

Not able to access the data inside of an object

I am fetching id column value from database for a particular email. In this case I am passing email and want to get primary key i.e id. This operation is successful as I get object which contains Object with the right and expected result. However I am not able to access the object.
I am receiving object like this:
[ UserInfo { id: 21 } ]
And I am not able to access id part of it.
I am using node.js, postgres for database and typeorm library to connect with database.
const id = await userRepo.find({
select:["id"],
where: {
email:email
}
});
console.log(id)
This prints the above object.
The id I am getting is right. But I am not able to retrieve the id part of the object. I tried various ways for e.g.
id['UserInfo'].id, id.UserInfo.
Please help me in accessing the object I am receiving
Typeorm .find() returns an array of objects containing entries corresponding to your filters, in your case, all entries with an email field corresponding to the email you specified.
Because the result is an array, you can access it this way:
const records = await userRepo.find({
select: ['id'],
where: {
email,
},
})
console.log(records[0].id)
You could also use the .findOne() method, which returns a single element and might be a better solution in your case :)
When you are putting a field in the select part select:["id"], you are only retrieving this part of the database.
It is like your query was this: select id from userRepo where email = email
and you need to put * in the select part to retrieve all the information:
const id = await userRepo.find({
select:["*"],
where: {
email:email
}
});

Creating view to check a document fields for specific values (For a simple login)

I'm very new to cloudant , so pardon me for this question. I am creating a simple mobile game login system which only checks for username(email) and password.
I have several simple docs that are in this format
{
"_id": "xxx",
"_rev": "xxx",
"password": "3O+k+O8bxsxu0KUlSBUiww==", --encrypted by application beforehand
"type": "User",
"email": "asd#asd.com"
}
Right now I can't seem to get the correct 'Formula' for creating this view (map function) whereby I would do a network request and pass it both the email and password. If there is a doc that matches the email, then check the doc.password against the passed value. If it matches, the function should return a simple "YES".
For now my map function is as follows, but this just returns all the docs .
function(doc) {
if (doc.email){
index("password", doc.password, { store : true });
if (doc.password){
emit("YES");
}
}
}
It may be my request format is also wrong. Right now it is as follows. Values are not real, only for format checking
https:/etcetc/_design/app/_view/viewCheckLogin?q=email:"asd#asd.com"&password:"asd"
It looks like you have misunderstood how views are supposed to work. In general you cannot perform logic to return a different result based on the request. Query parameters in a view request can only be used to limit the result set of view entries returned or to return grouped information from the reduce function.
To determine if there is a match for a given username and password you could emit those values as keys and then query for them. This would return the view entry for those keys or an empty list if there was no match. However I'd be very cautious about the security here. Anyone with access to the view would be able to see all the view entries, i.e. all the usernames and passwords.

Mongoose getter / setters for normalizing data

I have User schema which has a username field. I would like this field to be case sensitive, so that users may register names such as BobDylan. However, I need my schema to validate new entries to check there are no duplicates, incase sensitive, such as bobdylan.
My research has taught me that I should create an additional field in the schema for storing a lower case / upper case version, so that I can easily check if it is unique. My question is, how would I achieve this with the Mongoose API?
I have tried using a set function, such as:
UserSchema.path('username_lower_case').set(function(username_lower_case) {
return this.username.toLowerCase()
});
However, this function doesn't seem to be running. I basically need to tell username_lower_case to be whatever username is, but in lower case.
One way would be to use a pre-save hook to do it.
UserSchema.pre('save', function (next) {
this.username_lower_case = this.username && this.username.toLowerCase();
next();
});
Another way would be to make username a virtual:
UserSchema.virtual('username').set(function (value) {
this.username_raw = value;
this.username_lower_case = value && value.toLowerCase();
}).get(function () {
return this.username_raw;
});

Resources