Mongoose/mongodb return null when user exists by id - mongodb

Im having trouble that my userid ( aka _id created by mongodb) wont let me search .
here is my user
db.users.find({})
{ "_id" : ObjectId("5912073cd87a401dd196a820"), "password" : "$2a$10$Sj/bxhSzeL8xzZYn8Vl71OjrG9Ayly9ueDi2O1iDwi7N4vYyZGWKi", "username" : "malin", "inFamily" : false, "bank" : 500, "defence" : 1, "attack" : 1, "cash" : -494055600, "xp" : 0, "rank" : 1, "bullets" : 0, "location" : 1, "permission" : 0, "health" : 0, "__v" : 0 }
as seen here its one with id 5912073cd87a401dd196a820 .
Here is the function im always calling.
function userDetails(userid) {
return new Promise(function(resolve, reject) {
console.log("search: " + userid);
// Users.findById(userid, function (result) {
Users.findOne({_id: userid},function(result) {
console.log("search done");
console.log(result);
return resolve(result);
});
});
}
I use the function all over my site, on some things its works, others it wont.
For example. when component 1 calls it it works, when component 2 tries, it fails.
None of the findByid or findOne works when its failing.
Here is the query my site ran on one of my components that is failing:
search: 5912073cd87a401dd196a820
Mongoose: users.findOne({ _id: ObjectId("5912073cd87a401dd196a820") }, { fields: {} })
logging /api/gameapi?action=getcrimemembers
navigate: false
search done
null
But every results is null/ false, how come?

Use this i'ts must work good. Mongoose function already returned promise so you don't need wrap it in function:
Users.findOne({_id: userid}).then(result=>{...}).catch(err=>{...})

Related

Mongoose updateMany :: wont find any on given condition

I have updateMany function as follows
Article.updateMany({author: userId}, {author: anonym}, function(err, updated) {
if (err) {
res.send(err);
} else {
res.send(updated);
}
});
userId is = 6068b57dbe4eef0b579120c7
anonym is = 6069870676d6320f39e7e5a2
for testing purposes I have a single article in MongoDB as follows
db.articles.find()
{ "_id" : ObjectId("6068b591be4eef0b579120c8"), "favoritesCount" : 1, "comments" : [ ], "tagList" : [ ], "title" : "Martin", "description" : "Testib", "body" : "Asju", "author" : ObjectId("6068b57dbe4eef0b579120c7"), "slug" : "martin-2hzx78", "createdAt" : ISODate("2021-04-03T18:36:01.977Z"), "updatedAt" : ISODate("2021-04-03T18:53:29.809Z"), "__v" : 0 }
You can see that article has "author" : id field in it which currently shows userId as author.
I want to update that field and transfer authorship to anonym user.
When I send this request to postman I get following response
{
"n": 0,
"nModified": 0,
"ok": 1
}
And database remains unchanged. What am I doing wrong here ?

What are the efficient query for mongodb if value exist on array then don't update and return the error that id already exist

I have an entry stored on my collection like this:
{
"_id" : ObjectId("5d416c595f19962ff0680dbc"),
"data" : {
"a" : 6,
"b" : [
"5c35f04c4e92b8337885d9a6"
]
},
"image" : "123.jpg",
"hyperlinks" : "google.com",
"expirydate" : ISODate("2019-08-27T06:10:35.074Z"),
"createdate" : ISODate("2019-07-31T10:24:25.311Z"),
"lastmodified" : ISODate("2019-07-31T10:24:25.311Z"),
"__v" : 0
},
{
"_id" : ObjectId("5d416c595f19962ff0680dbd"),
"data" : {
"a" : 90,
"b" : [
"5c35f04c4e92b8337885d9a7"
]
},
"image" : "456.jpg",
"hyperlinks" : "google.com",
"expirydate" : ISODate("2019-08-27T06:10:35.074Z"),
"createdate" : ISODate("2019-07-31T10:24:25.311Z"),
"lastmodified" : ISODate("2019-07-31T10:24:25.311Z"),
"__v" : 0
}
I have to write the query for push userid on b array which is under data object and increment the a counter which is also under data object.
For that, I wrote the Code i.e
db.collection.updateOne({_id: ObjectId("5d416c595f19962ff0680dbd")},
{$inc: {'data.a': 1}, $push: {'data.b': '124sdff54f5s4fg5'}}
)
I also want to check that if that id exist on array then return the response that following id exist, so for that I wrote extra query which will check and if id exist then return the error response that following id exist,
My question is that any single query will do this? Like I don't want to write Two Queries for single task.
Any help is really appreciated for that
You can add one more check in the update query on "data.b". Following would be the query:
db.collection.updateOne(
{
_id: ObjectId("5d416c595f19962ff0680dbd"),
"data.b":{
$ne: "124sdff54f5s4fg5"
}
},
{
$inc: {'data.a': 1},
$push: {'data.b': '124sdff54f5s4fg5'}
}
)
For duplicate entry, you would get the following response:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
If matched count is 0, you can show the error that the id already exists.
You can use the operator $addToSet to check if the element already exits in the array.
db.collection.updateOne({_id: ObjectId("5d416c595f19962ff0680dbd")},
{$inc: {'data.a': 1}, $addToSet: {'data.b': '124sdff54f5s4fg5'}}
)

StrongLoop: does it support Limit Fields to Return from a Query for MongoDB databases?

Does anyone know if strongloop supports limit fields to return from a Query for MongoDB databases? I think strongloop doesnt support all the MongoDB query features so I'm afraid this might not be supported.
This is what I want to achieve using strongloop:
https://docs.mongodb.org/v3.0/tutorial/project-fields-from-query-results/
MongoDB operations example (executed within the database):
Without Limiting the Fields:
> db.Releases.find({epoch_time: {$gte: 1451417675, $lt: 1483717675}})
{ "_id" : ObjectId("5682bbcbab755688f9bfd939"), "release_id" : 3, "event_id" : 1, "epoch_time" : 1451417675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93a"), "release_id" : 4, "event_id" : 2, "epoch_time" : 1452717675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93b"), "release_id" : 5, "event_id" : 2, "epoch_time" : 1453717675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93c"), "release_id" : 6, "event_id" : 3, "epoch_time" : 1461207675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93d"), "release_id" : 7, "event_id" : 3, "epoch_time" : 1461407675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93e"), "release_id" : 8, "event_id" : 4, "epoch_time" : 1461417675 }
{ "_id" : ObjectId("5682bbccab755688f9bfd93f"), "release_id" : 9, "event_id" : 1, "epoch_time" : 1472717675 }
{ "_id" : ObjectId("5682bbd1ab755688f9bfd940"), "release_id" : 10, "event_id" : 5, "epoch_time" : 1473717675 }
Limiting the fields:
> db.Releases.find({epoch_time: {$gte: 1451417675, $lt: 1483717675}},{_id:0,release_id:0,event_id:0})
{ "epoch_time" : 1451417675 }
{ "epoch_time" : 1452717675 }
{ "epoch_time" : 1453717675 }
{ "epoch_time" : 1461207675 }
{ "epoch_time" : 1461407675 }
{ "epoch_time" : 1461417675 }
{ "epoch_time" : 1472717675 }
{ "epoch_time" : 1473717675 }
I tried something like this in StrongLoop but I still get all the fields in the query.
Release.find({where: {...query expression...} },
{_id:0,release_id:0,event_id:0}, //trying to limit return fields
function (err, releases) {
...
}
);
Thanks,
Carlos
Yes, loopbackjs supports limiting fields in query. Diffrence between limiting fileds in mongodb and loopback query is that loopbackjs defaults return all fields to false when using fields filter. You have to explicitly say which fields you want query to return.
Release.find({where: {release_id : 4}, fields: {epoch_time: true}}, //return only epoch_time
function (err, releases) {
...
}
);
fields filter docs
According to the strongloop docs - https://docs.strongloop.com/display/public/LB/Querying+data
It provides ability to add multiple options for querying, filtering, limiting data on both REST endpoints as well as in Model Methods.
You can limit the fields in output in a remote method like this -
Release.find(
{ fields : {"epoch_time":true}
}, function(err, releases) {
// ... your code here
} );
Or you can do it in operation hooks like this as specified in https://docs.strongloop.com/display/public/LB/Operation+hooks -
MyModel.observe('access', function logQuery(ctx, next) {
console.log('Accessing %s matching %s', ctx.Model.modelName, ctx.query.where);
next();
});
Creating a function inside our models
MyModel.observe('access', function logQuery(ctx, next) {
Release.find({
where: {
release_id: 4
}
});
});

Post object from backbone to REST

I am trying to post data from front-end to RESTful. I'm a backbone beginner, so my problems are probably easy to solve. But have struggled with this all day - so now I'm asking for guidance.
I have a button that use to add data to REST. So in my view I use object.save(); to save an object to model.
Here is my model:
define(["underscore" , "backbone"],function(_ , Backbone){
var Test = Backbone.Model.extend({
url:'http://mysite.com/Test/Test.svc/AddTest',
idAttribute: 'ID'
});
return Test;
});
View :
define(["jquery" ,
"underscore" ,
"backbone" ,
'models/Test',
'views/Test',
],function($ , _ , Backbone , Test, TestView){
var HomeView = Backbone.View.extend({
initialize: function() {
//....
},
events : {
"click #byn" : function(){
//....
},
'click #test' : 'addTest'
},
addTest : function(){
var object = new Test();
object.set({
"ID" : 0,
"Name" : "",
"CustomerID" : 106,
"Type" : 0,
"LastUpdated" : "\/Date(1383152400000+0700)\/",
"Detail" : [
{
"ID" : 0,
"TID" : 0,
"ItemID" : 22776,
"Quantity" : 2,
"LastUpdated" : "\/Date(1383152400000+0700)\/"
}
]
});
object.save();
var _wlView = new TestView({model:object});
},
render : function(){
//....
}
});
return HomeView;
});
To be truth, I really don't know how could I post the object that I have saved in my view object.save(); to the restful throw the rest url like http://mysite.com/Test/Test.svc/AddTest.
Url of model should be declared as urlRoot value and it is better to have it relative (e.g. "/AddTest").
Then the backend route for save action will be "actual url" + "urlRoot".

Weird MongoDB MapReduce ObjectId.toString() behavior?

I've run into some strange differences between the mongodb running on MongoHQ and the version running on my own development machine. Specifically, when calling .toString() on an object id inside a MapReduce map function, the results vary:
On my own machine:
ObjectId('foo').toString() // => 'foo'
On MongoHQ:
ObjectId('foo').toString() // => 'ObjectId(\'foo\')'
Note: The id's I use are actual mongodb id's - not just 'foo' etc. as in these examples
I would expect .toString() to behave like on my own machine - not how it's behaving on MongoHQ. How come it's not?
My local OSX version of MongoDB is installed using Homebrew and is version 2.0.1-x86_64
To show what's actually going on, I've build a little test case. Let's assume that we have a users collection with a friends attribute, being an array of user ids:
> db.users.find()
{ _id: ObjectId('a'), friends: [ObjectId('b'), ObjectId('c')] },
{ _id: ObjectId('b'), friends: [] },
{ _id: ObjectId('c'), friends: [] }
As you can see a is friends with b and c where as b and c isn't friends with anybody.
Now let's look at a working test-algorithm:
var map = function() {
this.friends.forEach(function(f) {
emit(f, { friends: 1, user: user, friend: f.toString() });
});
};
var reduce = function(k, vals) {
var result = { friends: 0, user: [], friend: [] };
vals.forEach(function(val) {
result.friends += val.friends;
result.user.push(val.user);
result.friend.push(val.friend);
});
return result;
};
var id = ObjectId('50237c6d5849260996000002');
var query = {
query : { friends: id },
out : { inline: 1 },
scope : { user: id.toString() },
jsMode : true,
verbose : true
};
db.users.mapReduce(map, reduce, query);
Assuming id is set to an id of a user who is a friend of someone in the users collection, then the output returned by the mapReduce method on MongoHQ will look like this:
{
"results" : [
{
"_id" : ObjectId("50237c555849260996000001"),
"value" : {
"friends" : 1,
"user" : "50237c6d5849260996000002",
"friend" : "ObjectId(\"50237c555849260996000001\")"
}
},
{
"_id" : ObjectId("50237c74c271be07f6000002"),
"value" : {
"friends" : 1,
"user" : "50237c6d5849260996000002",
"friend" : "ObjectId(\"50237c74c271be07f6000002\")"
}
}
],
"timeMillis" : 0,
"timing" : {
"mapTime" : 0,
"emitLoop" : 0,
"reduceTime" : 0,
"mode" : "mixed",
"total" : 0
},
"counts" : {
"input" : 1,
"emit" : 2,
"reduce" : 0,
"output" : 2
},
"ok" : 1,
}
As you can see, the friend attribute in each result is not just a string containing the id, but a string containing the actual method call.
Did I run this on my own machine, the results array would have been:
{
"_id" : ObjectId("50237c555849260996000001"),
"value" : {
"friends" : 1,
"user" : "50237c6d5849260996000002",
"friend" : "50237c555849260996000001"
}
},
{
"_id" : ObjectId("50237c74c271be07f6000002"),
"value" : {
"friends" : 1,
"user" : "50237c6d5849260996000002",
"friend" : "50237c74c271be07f6000002"
}
}
MongoHQ is running a different version of MongoDB than you are.
To get the behavior of your homebrew version, try changing your map function:
var map = function() {
this.friends.forEach(function(f) {
emit(f, { friends: 1, user: user.str, friend: f.str });
});
};