New to MongoDB so I hope I get the terminology correct...
I have a database that includes a user collection. In node I would like to check that value of a field, however, first I need to ensure the field exists.
For example here is my user schema:
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
local: {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
}
}
Some users have both a local and facebook documents/fields? whereas others may have either.
I wish to confirm the is the current user document has an email value in both fields if both fields exist in the document. i.e.
User.local.email & User.facebook.email
If I try to access the email field directly and the field does not exist for that document I get:
TypeError: Cannot read property 'email' of undefined
Try this -
var localExists = User.local != null;
var facebookExists = User.facebook != null;
if(localExists && facebookExists){
// both exist so check if both have email
var bothHaveEmail = User.local.email != null && User.facebook.email != null;
}
else if(localExists){
// only local exists
}
else if (facebookExists){
// only facebook exists
}
else{
// nothing exists
}
You could try
const localEmail = user.local && user.local.email;
const fbEmail = user.facebook && user.facebook.email;
If either is set to undefined that means that that email field doesn't exist
Related
Hello I am trying to check if someone has an object in his inventory witch quick.db
But when I try, whatever the artist is it always says that it's the inventory of the user. Here's the code that I use.
const db = require('quick.db');
let discord = require('discord.js');
module.exports = {
name : 'test',
description : "commande test",
async execute(message, args) {
const artist = message.content.slice(7).trim();
if(!artist){
message.channel.send("Spécifier l'artiste")
}
if(db.has(message.author.id, artist)){
message.channel.send("Artiste Present")
}
else{
message.channel.send("Non présent")
}
}
}
I use this to add information to the database
if (reaction.count == 2){
db.push(user.id, name_artist);
The problem is that you are only checking if the database has a specific user id as a key. According to the quick.db docs.
To check if an artist is stored in an array I would try this.
if (db.get(message.author.id).includes(artist)) {
message.channel.send("Artiste Present")
}
else {
message.channel.send("Non présent")
}
i have four object ids in an array . i also have a user id. i would like to remove the user id from array of object ids
allowners= [ 5d6caefdbb6f2921f45caf1d, 5d6caee9bb6f2921f45caf1b,
5d6dfcd6e3b11807944348b8, 5d6caefdbb6f2921f45caf1d]
user._id = 5d6caefdbb6f2921f45caf1d
what i tried
const userid = user._id
const vendors = allowners.filter((item) => userid !== item)
The result i got is
vendors = [ 5d6caefdbb6f2921f45caf1d,
5d6caee9bb6f2921f45caf1b,
5d6dfcd6e3b11807944348b8,
5d6caefdbb6f2921f45caf1d ]
the result i am expecting is
vendors = [ 5d6caee9bb6f2921f45caf1b,5d6dfcd6e3b11807944348b8]
If these ids in allowners array are Mongoose ObjectID you'll need to use .equals method on the ObjectID object to compare:
user._id = "5d6caefdbb6f2921f45caf1d"; //even if this is an ObjectID of mongoose
const userid = user._id;
const vendors = allowners.filter(item => !item.equals(userid));
Another Way: Using toString() on ObjectID (will only work when compared to a string -- userid)
vendors = allowners.filter(item => item.toString() !== userid);
Output:
console.info("Filtered IDs::", vendors);
Filtered IDs:: [ 5d6caee9bb6f2921f45caf1b, 5d6dfcd6e3b11807944348b8 ]
Your result should compute to the expected result if your data type match properly. For example:
// Your array of IDs of type {String}
const allowners = ['5d6caefdbb6f2921f45caf1d', '5d6caee9bb6f2921f45caf1b', '5d6dfcd6e3b11807944348b8', '5d6caefdbb6f2921f45caf1d'];
// Your user object with an id of type {String}
const userObject = {
id: '5d6caefdbb6f2921f45caf1d'
}
// Extract the id from your user object, and store in a userId variable If you wish :-)
const userId = userObject.id;
// Using your code with just changes in the variable name (userid -> userId)
const vendors = allowners.filter((item) => userId !== item);
// The result
console.log(vendors); // [ '5d6caee9bb6f2921f45caf1b', '5d6dfcd6e3b11807944348b8' ]
When user submits a content into my node.js app, he puts four things: start_date, his facebook username, text content and a flag, whether the content should be visible to everyone or only to his facebook friends.
When user fetches content, he can get the public content from other users and the content from his facebook friends (even when they submitted their content only for their friends).
I created a mongoose query that works correctly in this scenario. I do it like this:
var query = Test.find({})
if(startDate != undefined) {
var startDate = new Date(req.param('startDate'));
query = query.where('updated_at').gte(startDate);
}
if (friends != undefined) {
var friendsSplitted = friends.split(",");
for(var i=0; i<friendsSplitted.length; i++) {
query = query.or([{ 'facebook_username': friendsSplitted[i] }]);
}
}
query = query.where('hidden').equals(false);
if (publicFlag != undefined && publicFlag === "true") {
query = query.or({friends_only: false});
}
With that code above, when user queries only for content from his friends (that might be private or public), he POSTs startDate, an array of his friends, a flag hidden set to false and publicFlag set to false. A query is constructed:
Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, hidden: false, '$or': [ { facebook_username:
'XXXXXXXXXXXXXX' }, { facebook_username: 'YYYYYYYYYYYYYYY' } ] }) {
fields: undefined }
User can also query not only his friends (private or public) content, but also public content of everyone else. For that, he POSTs startDate, an array of his friends, a flag hidden set to false and publicFlag set to true. A query is constructed:
Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, hidden: false, '$or': [ { facebook_username:
'XXXXXXXXXXXXXX' }, { facebook_username: 'YYYYYYYYYYYYYYY' }, {
friends_only: false } ] }) { fields: undefined }
Above code works fine.
I want to add another case, when user can fetch content with specific hashtags.
Basically, when user selects this option, he can see other users' content that only includes those hashtags. That content though is his fb friends posts (private or public) and other people's posts (that is public).
For that I thought about adding this condition to my original node.js code:
if (hashtagsInput != undefined) {
var hashtags = hashtagsInput.split(",");
for(var i=0; i<hashtags.length; i++) {
query = query.or([{ 'hashtags': hashtags[i] }]);
}
}
but this solution does not work properly.
When user wants to fetch (private and public) content of his friends and public content of others - but only that one that contains one of the hashtags - he POSTs startDate, an array of his friends, a flag hidden set to false, publicFlag set to true and an array of his hashtags. When he does it, it creates a query:
Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, '$or': [ { hashtags: 'test1' }, { hashtags: 'test2'
}, { facebook_username: 'XXXXXXXXXXXX' }, { facebook_username:
'YYYYYYYYYYYYYYYYYY' }, { friends_only: false } ], deleted: false }) {
fields: undefined }
Basically I want to limit the general query only to specific hashtags.
This query does not return correct data. Now I'm not a mongoose specialist and I've spent couple hours yesterday of trying to figure it out, but I think the problem is that it returns the data that either contains one of the hashtags OR its author is one of my facebook friend.
I would like to fix this query so that - in case user POSTs hashtags - it fetches the content that is public and private of his friends and public of everyone, but only that one that contains at least one of those hashtags. And when user does not provide the hashtags - it should work as it was, fetching all private and public content of his friends and public of everyone.
Can you please help me fix my node.js code so that it creates a correct mongoose query?
The below code will work as you want
var query= {};
query.$and = [];
// and condition on start date
if(startDate != undefined) {
var startDate = new Date(req.param('startDate'));
query.$and.push({"updated_at":{$gte: startDate}});
}
// and condition on hastags
if (hashtagsInput != undefined) {
var hashtags = hashtagsInput.split(",");
query.$and.push({"hashtags":{$in: hashtags}});
}
// and condition on hidden
query.$and.push({"hidden":false});
// creating a OR condition for facebook friends and public flag
var friend_query = {};
friend_query.$or = [];
if (friends != undefined) {
var friendsSplitted = friends.split(",");
friend_query.$or.push({"facebook_username":{$in: friendsSplitted}});
}
if (publicFlag != undefined && publicFlag === "true") {
friend_query.$or.push({friends_only: false});
}
//Merging facebook friend condition with other condition with AND operator.
query.$and.push(friend_query);
var finalquery = Test.find(query)
Sorry I use to create mongodb query directly in Json format, it is little different than you are doing. This will work as you mentioned you want in question.
If it don't solve your problem tell me.
I'm trying to get the object id after adding it to the db (using collection.insert)
mongoose.model('Persons').collection.insert(person, function(err, newPerson) {
console.log('lets see you', newPerson);
});
and from the console I'm getting only result: { ok: 1, n: 1 } in stand of the new obj, any ideas how can I rich to the new object ?
thanks!
You can use save() here
var Persons = mongoose.model('Persons');
var personJSON = {
..... // persons schema values you want to insert
};
var person = new Persons(personJSON);
var result = yield person.save();
result variable will contain all the fields you inserted along with _id
In my node app I have designation model with following Schema.
var DesignationSchema = new Schema({
_id : ObjectId,
designation : String
});
And this is embedded in users Schema.
var UserSchema = new Schema({
fname:String,
lname :String,
email :String,
password :String,
designations : [DesignationSchema]
});
User can select one / many designations from select list. Below is my jade implementation for creating select list;
select(name="designations")
- for(var i = 0; i < designations.length; i++) {
option(value="#{designations[i]}", name="designations[#{i}]") #{designation.designation}
- }
But these values are stored as string array instead of DesignationSchema array:
{
designations : ["{designation:'Some Value' , _id : __DESIGNATION__ID}", "{designation:'Some Value' , _id : __DESIGNATION__ID}"]
}
UPDATE
I am pushing designations in following way in expressjs :
var newUser = new User(user.info);
if(user.designations && user.designations.length){
for(var i =0; i < user.designations.length; i ++) {
newUser.designations.push(user.designations[i]);
//I have tried JSON.parse(user.designations[i]) but it raises error that says : 'Unexpected token d'
//user.designations[i] object is something like : {designation:'Some Content', _id : __DESIGNATION__ID}
//IMPORTANT : the __DESIGNATION__ID is not inside single (') or double (") quotes. And I think this is the reason why JSON.parse is raising the error.
}
}
You can ommit the _id from DesignationSchema as Mongoose will add that for you itself. Make sure you JSON.stringify the data you POST/PUT/etc so that you are left with something you can parse.
You may also need to specify the content-type as application/json when you send the data back. This should allow you to avoid JSON.parse in your endpoint.