MongoDB ObjectID in JS - javascript

I am trying to make pagination work with MongoDB without skip();
In mongo shell I got the following results with my query, but in Javascript a empty [];
I think I am doing the ObjectID wrong, I use the "mongodb ObjectID" and "mongojs" libs with Node.js.
Mongo shell:
db.chat.find({
_id: { $lt: ObjectId("53e901c125c68270311e5f41") },
user_id: 1,
target_user_id: 1,
"$or": [{user_id: 1, target_user_id:1}]
}).sort({
ts: -1
}).limit(5);
Output:
{ "_id" : ObjectId("53e88e1bb76e781413000029"), "user_id" : 1, "target_user_id" : 1, "message" : "Hey" }
{ "_id" : ObjectId("53e88f51b76e78141300002a"), "user_id" : 1, "target_user_id" : 1, "message" : "Hey" }
//ect.
Javascript
var ObjectID = require('mongodb').ObjectID;
var db = require("mongojs").connect(db_uri, db_collections);
//last_ts = "53e901c125c68270311e5f41"
var last_id = ObjectID.createFromHexString(last_ts);
db.chat.find({
_id: { $lt: last_id },
user_id: 1,
target_user_id: 1,
"$or": [{user_id: 1, target_user_id:1}]
}).sort({
ts: -1
}).limit(5).toArray(function (err, docs) {
console.log("docs:"+docs); //"docs" - no result
console.log("err:"+err); //"err:null"
if(docs != null){
console.log(JSON.stringify(docs)); //"docs:[]"
}
});
How can I get the same result, with my query in JS?
Edit with $oid from the docs:
http://docs.mongodb.org/manual/reference/mongodb-extended-json/#oid
Still not working..
var last_ts = "53e901c125c68270311e5f41";
db.chat.find({_id: {$lt: {"$oid": last_ts}}, user_id:1, target_user_id:1, "$or": [{user_id: 1, target_user_id:1}]}).sort({ts: -1}).limit(5)
Edit
Now working with simply as:
var last_ts = "53e901c125c68270311e5f41";
new ObjectID(last_ts)

If I'm not mistaken, you can simply pass the ObjectID string to the mongo query:
db.chat.find({
_id: { $lt: last_ts},
user_id: 1,
target_user_id: 1,
"$or": [{user_id: 1, target_user_id:1}]
})
...

Related

mongodb find specific column and change timestamp to date

I try to query data from mongodb with spesific column, at first it returns all the value and columns i need but then when i try to change the value of the timestamp to date it shows error like this
Options must be an object, got \"_id formId title username date createdAt\"
Here is my code
const answers = await Answer.find(
{ userId: req.params.userId },
{ $toDate: "createdAt" },
"_id formId title username date createdAt"
);
i wonder where did i do wrong here...
Try using aggregate:
const answers = await Answer.aggregate([
{ $match: { userId: req.params.userId } },
{
$project: {
formId: 1,
title: 1,
username: 1,
date: 1,
createdAt: { $toDate: '$createdAt' },
},
},
]);

Mongoose find function to search not returning desired results

I have a list of users in Mongodb that needs to searched according to some filters as shown in below picture:Only gender is mandatory and users may or may not have other details
User.find({
"gender": userEntry.gender,
"dob": { $gte: convert.getDobFromAge(userEntry.ageHigherLimit), $lte: convert.getDobFromAge(userEntry.ageLowerLimit), $exist: false },
"details.chest": { $gte: userEntry.chestLowerLimit, $lte: userEntry.chestHigherLimit, $exist: false },
"details.waist": { $gte: userEntry.waistLowerLimit, $lte: userEntry.waistHigherLimit, $exist: false },
"details.height": { $gte: userEntry.heightLowerLimit, $lte: userEntry.heightHigherLimit, $exist: false },
"details.weight": { $gte: userEntry.weightLowerLimit, $lte: userEntry.weightHigherLimit, $exist: false }
}, function (err, users) {
return res.render('client/search.html', { users: users });
});
Above is the mongoose query to search and the userEntry looks like this
userEntry={
"gender":2,
"ageLowerLimit":28,"ageHigherLimit":40,
"chestLowerLimit":"","chestHigherLimit":"",
"heightLowerLimit":"","heightHigherLimit":"",
"waistLowerLimit":"","waistHigherLimit":"",
"weightLowerLimit":"","weightHigherLimit":"",
"state":"","city":"",
"country":"","skin_color":"",
"profession_type":"","experience":"",
"hair_type":""
}
My problem is the find function , it should search all records with gender as '2' and age>=28 and age=<40 (from the above query gives me empty array even though one record satisfies it),giving all the results that satisfy the above conditions irrespective of whether other fields are empty or doesnot exist.
Any help would be appreciated.
As rightly suggested changed the query to but still 0 records fetched
var query = {
details: {}
};
if (userEntry.gender) {
query.gender = userEntry.gender;
}
if(userEntry.ageLowerLimit && userEntry.ageHigherLimit ) {
query.dbo = { $gte: convert.getDobFromAge(userEntry.ageHigherLimit), $lte: convert.getDobFromAge(userEntry.ageLowerLimit)};
}
console.log(query);
User.find(query, function (err, users) {
if(!err) {
console.log(users);
return res.render('client/search.html', { users: users });
}
console.log(err);
});
});
one of the records trying to fetch
{ "_id" : ObjectId("59c3f47e6388613b94556b78"), "name" : "tanzeel", "email" : "im_tanzeel#yahoo.co.in", "password" : "$2a$10$kvachEZL0vEPPJiS7bIAMeGMXiZ.MRaZmrBECXB207jme1I4JEn6i", "created_at" : ISODate("2017-09-21T17:18:54.822Z"), "role" : 1, "following" : [ ], "dp" : "/dp/default.jpg", "gender" : 2, "__v" : 0, "dob" : ISODate("1994-11-29T00:00:00Z"), "details" : { "height" : 160, "weight" : 65, "profession_type" : "Actor", "skin_color" : "Tan", "eye_color" : "Black", "waist" : 32, "chest" : 35 } }
You got correct value from MongoDB but not your expected value because your query build not correct. Also $exist not valid operator should be $exists and you compare with empty string for some fields like details.waist = "" because userEntry.weightLowerLimit is empty. However you should build query correctly to get expected result.
can try like this...
var query = {
details: {}
};
if (userEntry.gender) {
query.gender = userEntry.gender;
}
if(userEntry.ageLowerLimit && userEntry.ageHigherLimit ) {
query.dbo = { $gte: convert.getDobFromAge(userEntry.ageHigherLimit), $lte: convert.getDobFromAge(userEntry.ageLowerLimit)};
}
if(userEntry.chestLowerLimit && userEntry.chestHigherLimit) {
query['details.chest'] = { $gte: userEntry.chestLowerLimit, $lte: userEntry.chestHigherLimit };
}
//... for others conditions
User.find(query, function (err, users) {
if(!err) {
return res.render('client/search.html', { users: users });
}
console.log(err);
});

mongoose update nested document not working

I try to figure out what I'm doing wrong that moongose is not updating my document. Just for testing the id's are hardcoded.
node.js
var id1 = "592fd471fedd311d5c76a024";
var id2 = "592fd4ad608e001d79938ba8";
Workshop.update({
_id: id1,
'themen._id': id2
}, {
'$set': {
'themen.$.risikolandschaft': ["John", "Doe"],
}
},
function(err, body) {
if (err) {
console.log(err)
} else {
console.log(body);
}
}
);
here my data copied from MongoDB Compass
{
"_id" : ObjectId("592fd471fedd311d5c76a024"),
"clientid" : "592cff8794738f0347609666",
"bezeichnung" : "Workshop 1.5.2017 / 10:46",
"themen" : [
{
"thema" : {
"__v" : 0,
"bezeichnung" : "Sturm",
"beschreibung" : "Text",
"_id" : "59255757b1485d0ad2a6924f"
},
"risikolandschaft" : [ "one", "two", "three"],
"date" : "2017-06-01T08:47:41.944Z",
"_id" : ObjectId("592fd4ad608e001d79938ba8")
}
], ...
the log from body
{ n: 0, nModified: 0, ok: 1 }
for adding a new item to the "themen" subdocument i use this:
var new_thema = {
_id: mongoose.Types.ObjectId(),
date : req.body.date,
risikolandschaft : req.body.risikolandschaft,
thema : req.body.thema };
here the mongoose schema
var WorkshopSchema = mongoose.Schema({
clientid: {
type: String,
required: true
},
bezeichnung: {
type: String,
required: true
},
stammdaten : [],
date : Date,
themen : []
});
and there is no subschema for "themen"
"mongoose": "^4.8.6"

How to sort inner array and match elements in mongoose

So I am trying to do a semi-complicated query in mongoose. It is as follows:
Event.findOne({ users: { $elemMatch: { user: someUserId, going: 1 }, sort: {createTime: -1} } }
Basically what I would like to do is find a single Event that has a user in its user array that matches an Id and is attending. I have multiple user records for each user in the user array so I want to find the most recent one, to do this I would like to sort the user array by createTime. This is where the error is coming in and it just returns undefined. It works just fine when I don't include the sort function, is there any way to include that?
Here is what my Event object looks like:
{
_id: 1,
endTime: 1429060173865,
createTime: 1429051773902,
startTime: 1429052973865,
description: 'some desc',
creator: 2,
users:
[ { user: 1,
status: 1,
going: 1,
createTime: 1429051773749,
_id: 552d997d8e923847306e2c21 },
{ user: 1,
status: 1,
going: 1,
createTime: 1429051773922,
_id: 552d997d8e923847306e2c25 },
{ user: 1,
status: 9,
going: 0,
createTime: 1429051773942,
_id: 552d997d8e923847306e2c26 } ],
destroyed: 0 }
Is there any way to make this query entirely in mongoose?
As part of find, MongoDB can't sort an array field of a document. You could define a virtual of Mongoose to return the array in sorted order. You could also maintain the array in sorted order, as shown below:
> db.test.drop()
// note: not in order when inserted
> db.test.insert({ "_id" : 0, "users" : [
{ "user" : 1, "going" : 1, "created" : 22 },
{ "user" : 2, "going" : 1, "created" : 775 },
{ "user" : 1, "going" : 1, "created" : 6432 }
] })
// insert user to array and sort as part of update
> db.test.update({ "_id" : 0 },
{ "$push" : {
"users" : {
"$each" : [{ "user" : 2, "going" : 1, "created" : 5532 }],
"$sort" : { "created" : -1 }
}
} })
> > db.test.findOne()
{
"_id" : 0,
"users" : [
{ "user" : 1, "going" : 1, "created" : 6432 },
{ "user" : 2, "going" : 1, "created" : 5532 },
{ "user" : 2, "going" : 1, "created" : 775 },
{ "user" : 1, "going" : 1, "created" : 22 }
]
}
That way, when you perform your find query, the arrays in the matching documents will already be in the desired order.
Your query is not correctly written. In order to sort you should write it in third argument of find:
Event.findOne(
{ users:
{ $elemMatch: { user: someUserId, going: 1 }}
},
null,
{
sort: {createTime: -1}
},
function(err, event) {
//your event here
});

MongoDB insert record issue

I have a Mongo DB structure which looks something like this :
db.users.find().pretty();
{
"_id" : ObjectId("52b42b148ffa91f7ebbe8ebc"),
"username" : "test",
"password" : "test",
"party" : [
"4988",
"5037"
],
"something" : [
"3571"
],
"ludilo" : [],
}
Im using express js in my app and this module for connecting to Mongo https://npmjs.org/package/mongodb ,
How can I insert one entry into "something" array for user with id that I get from session.
I tried something like this , but with no success
var collection = db.collection('users');
collection.find({'_id':new ObjectID(req.user.id)}).toArray(function(err, items) {
console.dir(items);
}).insert({"something":"1234"});
You can $push a value to an array with
db.users.update(
{ _id: ObjectId( "52b42b148ffa91f7ebbe8ebc" ) },
{ $push: { something: "1234" } }
)
or if you do not want any duplicates in your array you can use $addToSet
db.users.update(
{ _id: ObjectId( "52b42b148ffa91f7ebbe8ebc" ) },
{ $addToSet: { something: "1234" } }
)
You can try this code:
collection.find({_id: new ObjectID(req.user.id)}).toArray(function(err, items) {
var doc = items[0];
doc.something.push('1234');
collection.update({_id: doc._id}, {$set: {something: doc.something}}, {safe: true}, function() {
//your next actions
});
});
I run this code on my local machine and it seems to work fine

Categories

Resources