Hi I am trying to run MongoDB queries inside socket io functions.findOne is working correctly but find and aggregate functions are not working at all.enter code here
mongo.connect('mongodb://localhost:27017', function (err, client) {
const db = client.db('dbName');
const bookWalker = db.collection('bookwalkers');
const walker = db.collection('walkers');
io.sockets.on('connection', function (socket) {
socket.on('enterRoom', function (data) {
socket.room = data.room;
socket.join(data.room);
console.log("connected to room", data.room);
bookWalker.find({"pendingWalk._id":
ObjectId("5bd994d2f395622e0b8f71af")},async function(err,resp) {
console.log("dataf",resp);
io.sockets.in(data.room).emit('getStartTime', resp[0]);
});
});
});
});
this is Sample data in DB
{
"_id" : ObjectId("5bd994d2f395622e0b8f71ad"),
"pendingWalk" : [
{
"walkPicture" : [],
"status" : 0,
"walkPath" : [],
"_id" : ObjectId("5bd994d2f395622e0b8f71af"),
"bookedDate" : ISODate("2018-10-31T13:30:56.581Z"),
"bookedTime" : ""
}
],
"userId" : ObjectId("5b6e932062bce05ae5647980"),
"book_dt" : ISODate("2018-10-31T11:41:06.230Z"),
"__v" : 0}
the query is working fine inside mongo shell.
mongodb find() returns a cursor not array. You have to call toArray() function.
bookWalker.find({"pendingWalk._id":ObjectId("5bd994d2f395622e0b8f71af")}).toArray(function(err,resp){
console.log(resp[0]);
});
Related
I have a model userDatas and it contain a list of user data.
[{
"_id" : ObjectId("5bb6730721f28a295436b36f"),
"userId" : "5bb6730721f28a295436b36e",
"reputationNumber" : 0,
"questions" : [],
"answers" : []
},
{
"_id" : ObjectId("5bb6738c21f28a295436b371"),
"userId" : "5bb6738c21f28a295436b370",
"reputationNumber" : 0,
"questions" : [],
"answers" : []
}]
I want to filter by userId and add "5bb7d72af050ca0910282ff4" string to questions array. How to accomplish that?
//Userdatas.find
Since you are using mongoose you can use the findOneAndUpdate and addToSet to achieve this:
Userdatas.findOneAndUpdate(
{userId: "5bb7d72af050ca0910282ff4"},
{$addToSet: {questions: '5bb7d72af050ca0910282ff4'}},
function (err, result) {
...
}
)
The query would look something like
Userdatas.findOne({where: {userId: "5bb7d72af050ca0910282ff4"}}, function (err, data) {
if (!err && data) {
var questionsArr = [];
if (data.questions) {
questionsArr = data.questions;
}
questionsArr.push('5bb7d72af050ca0910282ff4');
data.updateAttributes({questions: questionsArr}, function(err, updateData) {
cb (err, updateData);
});
} else {
cb (err, {});
}
});
Unfortunately you would need 2 queries to do this. First, to get the document where the userId matches your required userId and to push the string to the questions array and update the document.
EDIT:
The first findOne query fetches the document where userId matches our user. The updateAttributes query is executed on the document that was fetched, so it updates the correct document.
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=>{...})
I'm working on a migration from mongodb to mysql. I have a sub document in one collection, I need to find the data using sub document.
The collection structures looks like this
{
"_id" : ObjectId("578506a90420bec15ea33783"),
"reselected" : "ABCDEFGH",
"reskip" : [],
"restatus" : "active",
"reuser" : {
"activeListings" : [
{
"subcategory" : "mobiles",
"title" : " Mobile 1",
"transactiontype" : "post"
},
{
"category" : "mobiles",
"title" : " Mobile 2",
"transactiontype" : "post"
} ],
"reuserInput" : "2",
"reussdsession" : "303757117" }
I have tried with mapreduce code
mr = db.runCommand({
"mapreduce" : "collection name",
"map" : function() { */map/
for (var key in "this.reuser.activeListings") {
for (var key1 in "this.reuser.activeListings"[key]) {
emit(key1, null);
}
}
},
"reduce" : function(key, stuff) { return null; }, /*reducer/
"out": "my_collection" + "_keys"
})
I need output for activeListings
{subcategory,title,transactiontype,category}
You essentially need to iterate the array and then emit each key. The following mapReduce script will give you the desired key list:
mr = db.runCommand({
"mapreduce": "collectionName",
"map": function() { /* mapper */
this.reuser.activeListings.forEach(function (obj){
for (var key in obj) { emit(key, null); }
});
},
"reduce": function() {}, /* reducer */
"out": "my_collection" + "_keys"
})
To get a list of all the dynamic keys, run distinct on the resulting collection:
> db[mr.result].distinct("_id")
["subcategory", "title", "transactiontype", "category"]
Hello I want to query with adding and subtraction on mongodb aggregation
This is what I do right now,
//schema for image
{
votes : {type:Number},
comments : {type :Array},
name : {type:String}
}
var o = {};
o.map = function () { emit(this._id, (4*(parseInt(this.votes)))+(3*(parseInt(this.comments.length)))+(0*(parseInt(this.views)))) }(parseInt(this.comments.length)))))/(parseInt(currentDate-this.created_at.getDate())+1) }
o.reduce = function (k,v) { return parseInt(v); }
o.out = { replace: 'trending_images' }
o.verbose = true;
Image.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime)
model.find({created_at:{
$gte : weekBack,
$lt:today
}}).sort('-value').limit(limit).skip(skip).exec(function (err, docs) {
async.mapSeries(docs,function (doc,cb){
cb(null,doc._id);
},function (err,ids) {
console.log("Trending mapreduce",JSON.stringify(ids),ids);
return cb({_id:{$in:ids}})
})
});
});
how do I make something similar in Aggregation framework?
UPDATE : This is what I tried.
Image.aggregate(
{$project : {
_id : 1,
trending : {
total_votes : {$multiply:["$votes", 4]},
total_comments : {$multiply:["$comments.length", 3]},
rank : {$sum:["$total_comments","$total_votes"]}
}
} },
{$match:{created_at:{
$gte : weekBack,
$lt:today
}}
},
{$sort : {rank:-1} }
,
function (err,images) {
console.log(err,images);
}
)
Not sure if this works because, it raises an error, [MongoError: no such cmd: aggregate]
I checked the version for mongodb and mongoosejs, mongodb is version MongoDB shell version: 2.4.1
mongoosejs is version 3.6.4
But still that error! what else I can try?
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 });
});
};