NodeJS with MongoDB - Trying to use two different collections data - node.js

I have the following code:
var res1 = db.collection('col1').find(query1).toArray();
var res2 = db.collection('col2').find(query2).toArray();
Promise.all([res1, res2])
.then(([resultRes1, resultRes2]) => {
console.log('resultRes1', res1);
console.log('resultRes2', res2);
debugger;
}).catch(console.error);
Now, each one of them is working great separately
my problem is that i want to run a function when both of them are done.
if i try to nest them i keep getting a "mongodb topology was destroyed" alert (even though all i do is read from those collection - i am not changing anything
any ideas? many thanks.

Post the code where you are trying to run something where both are done. Are you trying something like this?
var res1 = db.collection('col1').find(query1);
var res2 = db.collection('col2').find(query2);
Promise.all([res1, res2])
.then(([resultRes1, resultRes2]) => {
console.log('resultRes1', resultRes1);
console.log('resultRes2', resultRes2);
})
.catch(console.error);

var collection = db.collection(collection1);
var Res = collection.aggregate([{
$lookup: {
from: "collection2",
localField: "ID",
foreignField: "ID",
as: "Sample"
}
}], function(err, result) {
if (result != null) {
for (var i = 0; i < result.length; i++) {
delete result[i].Sample;
}
res.send(result);
}
})
};

Related

What is the actual perpose of this users.settings.sendAs.list() API And how to get the data from it?

working on some node js project and suddenly this api comes up but i don't have any idea about it like how it is working and what are the other approaches to do the same
Code :
const gmail = google.gmail(`v1`);
gmail.users.settings.sendAs.list(params, (err, response) => {
if (err) {
console.log("errrrrrrrr", err);
reject(constants.responseMessages.ERROR_GETTING_EMAIL_MESSAGES);
}
else {
var aliases = [];
response = response.sendAs;
var ignoreOwnerMail = 1;
if (deviceType) {
if (deviceType == 1 || deviceType == 2) {
ignoreOwnerMail = 0;
if (response.length > ignoreOwnerMail) {
return emailData(response).then(res=>{
for(var i=0;i<response.length;i++){
aliases.push({
email: response[i].sendAsEmail,
replyto: response[i].replyToAddress,
name: response[i].displayName,
alias: response[i].treatAsAlias,
url : res[i],
signature : response[i].signature
})
}
resolve(aliases);
}).catch(err=>{
console.log(err);
});
}
}else{
resolve(aliases);
}
}
for (var i = 0; i < response.length; i++) {
if(response[i].isDefault == true ){
aliasDetails.defaultSignature = response[i].signature || ""
}
if (response.length > ignoreOwnerMail) {
aliases.push({
email: response[i].sendAsEmail,
replyto: response[i].replyToAddress,
name: response[i].displayName,
alias: response[i].treatAsAlias,
signature : response[i].signature
})
}
}
aliasDetails.aliasArr = aliases;
return resolve(aliasDetails);
}
}
)
So, i checked the official site for the information
link of official documentation
In the documentation it is showing only one parameter which is user_id but here in the code it takes one function as well (i am new to node js so, i don't have much knowledge on this) so, why it takes that function and how can i do it in better way because this takes 1s of time and i don't know why.
so, if anyone can guide through this will be very helpful.
Thanks so much in advance.

Does Sequelize findAll [Op.or] return in order?

Let's say I have this very basic search
const from = 'something';
const to = 'somethingElse';
const firstSearchCondition = { from, to: 'test' };
const secondSearchCondition = { from: 'test', to };
const models = await Model.findAll({
where: {
[Op.or]: [
firstSearchCondition,
secondSearchCondition
],
},
});
const [toTest, fromTest] = models;
if (toTest && fromTest) {
// both models exist
}
when both models exist, is toTest 100% from firstSearchCondition? or the order is not guaranteed
Order is not guaranteed unless you use an order by clause. Regardless of the query.
Thanks to #Lev and some more researches on my side, what I've come up as solution is something like this:
hope it helps future people ( if you have any idea to make it better, hit me up )
let toTest = null;
let fromTest = null;
for (let i = 0; i < models.length; i += 1) {
if (models[i].to === 'test') {
toTest = models[i];
} else {
fromTest = models[i];
}
}
// check here if both exist

node.js blocking, non-blocking issue in for statement

How can I save all of the json into my mongoldb?
Strangely, only the first value is stored every time.
It might be blocking/non-blocking issue.
json = {
["name":"Karl","id":"azo0"],
["name":"Robert","id":"bdd10"],
["name":"Joan","id":"difj90"],
["name":"Hallyn","id":"fmak88"],
["name":"Michael","id":"vma91"]
};
for(var i = 0; i < json.length; i++){
id = json[i].id;
name = json[i].name;
var ctx = {"id":id,"name":name};
db.json_db.count(ctx).exec(function(err, count) {
if(count < 1){
var model = new User({
"name":json[i].name,
"id":json[i].id
});
model.save(function(){
console.log("ok"+i);
});
}
});
};
After inserting, all of datas are filled with ["name":"Karl","id":"azo0"]
To check out console.log("ok"+i), it prints always "ok0" not "ok1", "ok2", "ok3"... etc..
How can I prevent this issue?
Incase you're using Async package, this is an best way to solve your problem...
async.eachSeries(json, (item, done) => {
let user = new User(
{
"name":json[i].name,
"id":json[i].id
},
(err, user) => {
if(err){
// handle err
}
return done();
}
);
});
.exec() tells me you're using Mongoose. So your loop can rewritten as:
const json = [
{name: "Karl", id: "azo0"},
{name: "Robert", id: "bdd10"},
{name: "Joan", id: "difj90"},
{name: "Hallyn", id: "fmak88"},
{name: "Michael", id: "vma91"}
];
for (const item of json) {
const count = await db.json_db.count(item).exec()
if (!count) {
await new User(item).save()
}
}
Error handling omitted.
See http://exploringjs.com/es2016-es2017/ch_async-functions.html

What is the best way to loop bluebird promises

Now I've working on NodeJS and Sequelize to query and process an database data.
I've call findAll from Table1 and I want to query each rows to apply some data to Table2 then I want to add all data to array before send output, I did like this
var last_promise;
var output_results = {};
Table1Model.findAll()
.then(function(results1)
{
for (var i = 0; i < results1.length; ++i)
{
var result1 = results1[i];
output_results[result1.id] = result1;
var add_promise = Table2Model
.create({
id_from_table1: result1.id,
data_from_table1: result1.data
});
.then(function(result2) {
output_results[result2.id_from_table1].data2 = result2;
});
if (last_promise)
{
last_promise.then(function()
{
return add_promise;
});
} else {
last_promise = add_promise;
}
}
}
}
last_promise.then(function() {
return output_results;
}
I want to know that there any better way to execute promises sequentially in a loop like this ?
It looks like you can do that with .all() method:
Table1Model
.findAll()
.then(function(results1) {
return Promise.all(results1.map(function(result) {
return Table2Model
.create({
id_from_table1: result1.id,
data_from_table1: result1.data
})
.then(function(result2) {
...
});
}));
})
.then(function(output_results) {
});

nodejs mongodb $in [array] not working if array is a variable

This is very strange to me. If put the array onlyIds in the aggregation query of my db I get no results. If I however put the content of onlyIds that I get printed from line 5 which looks like:
["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"...]
Then it works. But not if I use the variable.
This function:
var onlyIds = [];
for (var i = 0; i < users.length; i++) {
onlyIds.push(users[i]._id);
}
console.log("ids: " + JSON.stringify(onlyIds)); <---------- not empty
db.collection('posts', function(err, collection) {
collection.aggregate([
{$match: {user_id: {$in: onlyIds}}}, <------- not working
{$match: {created:{$gte: 0}}},
{$sort:{"created": -1}},
{$skip: req.body.skip},
{$limit: req.body.limit}
],
function(err, posts) {
var errorNo, content, message;
if (err) {
errorNo = resSend.errorDB;
message = JSON.stringify(err);
} else {
errorNo = resSend.errorNo;
content = posts;
message = "";
--> console.log(JSON.stringify(posts));
}
resSend.sendResponse(res, resSend.errorNo, content, message);
});
});
So in short, why does this work:
{$match: {user_id: {$in: ["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"...]}}}
and this doesn't:
{$match: {user_id: {$in: onlyIds}}}
And the line that does not work, works perfectly in another function. Any ideas or enlightenments?
EDIT:
Switching to find and using the below answer like this:
collection.find({'user_id': {$in: onlyIdsX}}).toArray(function(err, posts)
does not work either.
ANSWER:
As the selected answer indicates below is when the variable you search for is an ObjectId or a string. For anyone else, make sure that the variable in the db is the same type as the one you try to match it with. In my case both were supposed to be strings, but one's in "onlyIds" were ObjectIds.
Try following code to modify your loop:
var ids = ["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"];
var obj_ids = [];
for (var i = 0; i < users.length; i++) {
obj_ids.push(new ObjectID(users[i]._id.toString()));
var obj_ids.push(users[i]._id); // <== This will not work if your DB has _id : ObjectID("xyz") [i.e. you are not overiding defaults]
}
And you should include var ObjectID = require('mongodb').ObjectID; into your code.
You should use .toArray(function(err,.. (Not in your case since you used aggregation framework).This will also cause issue if you are not using findOne() (For more info on this here is the link)
Following is the example which spots the issue (in comments) & working Code:
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db,
ObjectID = require('mongodb').ObjectID;
var BSON = require('mongodb').BSONPure;
var server = new Server('localhost', 27017, {
auto_reconnect: true
});
var MongoClient = require('mongodb').MongoClient
//let id = your _id, smth like '6dg27sh2sdhsdhs72hsdfs2sfs'...
var users = ["52e953942a13df5be22cf792","52cbd028e9f43a090ca0c1af","52e953942a13df5be22cf797"];
var obj_ids = [];
for (var i = 0; i < users.length; i++) {
obj_ids.push(new ObjectID(users[i].toString()));
//obj_ids.push(users[i]._id); // <== This will not work if your DB has _id : ObjectID("xyz") [i.e. you are not overiding defaults]
}
MongoClient.connect('mongodb://127.0.0.1:27017/YourDBName', function(err, db) {
console.log('err' + err);
db.collection('posts', function(error, collection) {
//collection.find({_id:{$in: users}}),function(err, docs) { //This will not work
collection.find({_id:{$in: obj_ids}}).toArray(function(err, docs) {
console.log("Printing docs from Array. count " + docs.length);
docs.forEach(function(doc) {
console.log("Doc from Array ");
console.dir(doc);
});
});
});
});

Resources