I'm trying to connect to a mongoDB DB, and make some processes on a collection, and close the collection when all the collection items were processed. when I'm trying to receive array.length, I get undefined.
Db = require('mongodb').Db;
Server = require('mongodb').Server;
const db = new Db(DB_NAME, new Server(HOST, PORT));
// connect to mongoDB
db.open(function (err, db) {
const Collection = db.collection(COLLECTION_NAME);
var items = Collection.find({});
var itemsLength = items.lebgth;
var itemsProcessed = 0;
items.forEach((item, index, array) => {
// some process like:
Collection.update({query}, {set}, callback)
itemsProcessed++;
if(itemsProcessed == array.length){
db.close();
// close connection if all items were processed
}
});
});
Is there any other way to do it?
Just use db.collection.count()
EDIT:
You can use the optional callback of forEach, as documented here:
items.forEach((item) => {
// some process...
}, (err) => db.close()); // close connection if all items were processed
check this!
Collection.stat()
Related
I want to create collection in mongoDB 4.2 but I want to check that is exist or not? I'm using Node.JS and Express and I'm NOT using Mongoose.
Please try this ::
const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'your DB url';
// Database Name
const dbName = 'your DB name';
// Create a new MongoClient
const client = new MongoClient(url);
// Use connect method to connect to the Server
client.connect(async function (err) {
if (err) console.log('Err::', err)
console.log("Connected successfully to server");
const collection = await client.db(dbName).listCollections({}, { nameOnly: true }).toArray()
console.log('List of all collections :: ', JSON.stringify(collection))
client.close();
});
You can use listCollections to find all the collection in your Database and loop over the returned array to get the names.
db.listCollections().toArray(function(err, items) {
console.log(items)
//and u can loop over items to fetch the names
});
I'm new to Node and MongoDB and I have a seemingly simple request. I've managed to connect to my database, and use a query to get my desired results. Now, I want to have this query continue indefinitely, since the end goal for my project is to plot data real time.
I would have thought a simple 'while (true)' loop would suffice, but that doesn't seem to be the case.
const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'mongodb://<username>:<password>#ds157614.mlab.com:57614/flight_data';
// Use connect method to connect to the Server
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
if (err) throw err;
var dbo = db.db("flight_data").collection("data");
while(true)
{
dbo.find().sort({_id: 1}).limit(1).toArray(function(err, result) {
if (err) throw err;
console.log("Temperature: " + result[0].data.temperature);
});
}
db.close();
});
I have found that the while loop is indeed running, but for some reason, the query just doesn't happen when inside the while loop. If you remove the while loop, the code functions fine. I just want it to continually print the results of the query being repeated.
Querying a DB continuously is inefficient and resource wasting, instead use change streams. It watches collection for any changes and will make the db call then only. Works only for Mongo 3.6+.
const MongoClient = require("mongodb").MongoClient;
// Connection URL
const url =
"mongodb://<username>:<password>#ds157614.mlab.com:57614/flight_data";
// Use connect method to connect to the Server
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
if (err) throw err;
const collection = db.collection("data");
const changeStream = collection.watch();
changeStream.on("change", next => {
// process next document
collection
.find()
.sort({ _id: 1 })
.limit(1)
.toArray(function(err, result) {
if (err) throw err;
console.log("Temperature: " + result[0].data.temperature);
});
});
db.close();
});
In the documentation of Algolia, for the node.js part they specified to use MySQL for indexing but not MongoDB, I have another question regarding this issue but it is more a general question , check here
Some folks ask me to use mongo-connector but tried it and I got some unknown error, which got me to square one
My real question is, how do i iterate a list of collections in mongodb to algolia?
This is the Algolia's version of MySQL in Node.js
var _ = require('lodash');
var async = require('async');
var mysql = require('mysql');
var algoliasearch = require('algoliasearch');
var client = algoliasearch("RQGLD4LOQI", "••••••••••••••••••••••••••••••••");
var index = client.initIndex('YourIndexName');
var connection = mysql.createConnection({
host: 'localhost',
user: 'mysql_user',
password: 'mysql_password',
database: 'YourDatabaseName'
});
connection.query('SELECT * FROM TABLE_TO_IMPORT', function(err, results, fields) {
if (err) {
throw err;
}
// let's use table IDS as Algolia objectIDs
results = results.map(function(result) {
result.objectID = result.id;
return result;
});
// split our results into chunks of 5,000 objects, to get a good indexing/insert performance
var chunkedResults = _.chunk(results, 5000);
// for each chunk of 5,000 objects, save to algolia, in parallel. Call end() when finished
// or if any save produces an error
// https://github.com/caolan/async#eacharr-iterator-callback
async.each(chunkedResults, index.saveObjects.bind(index), end);
});
function end(err) {
if (err) {
throw err;
}
console.log('MySQL<>Algolia import done')
};
To be specific I'm using mongoose as my ORM, so I have no experience in other libraries. Please help me on this, so that I could some searching interface already :(.
You can use the following code to iterate over the whole MongoDB mydb.myCollection collection + create batches that will be sent to the Algolia index:
var Db = require('mongodb').Db,
Server = require('mongodb').Server,
algoliasearch = require('algoliasearch');
// init Algolia index
var client = algoliasearch("*********", "••••••••••••••••••••••••••••••••");
var index = client.initIndex('YourIndexName');
// init connection to MongoDB
var db = new Db('mydb', new Server('localhost', 27017));
db.open(function(err, db) {
// get the collection
db.collection('myCollection', function(err, collection) {
// iterate over the whole collection using a cursor
var batch = [];
collection.find().forEach(function(doc) {
batch.push(doc);
if (batch.length > 10000) {
// send documents by batch of 10000 to Algolia
index.addObjects(batch);
batch = [];
}
});
// last batch
if (batch.length > 0) {
index.addObjects(batch);
}
});
});
I'm writing a server side code using node.js, I'm trying to get the MongoDB collection size using count method which is not working.
This is my code
var mongo = require('mongodb');
var host = "127.0.0.1";
var port = mongo.Connection.DEFAULT_PORT;
function getStock(name, callback) {
var db = new mongo.Db("testDB", new mongo.Server(host, port, {}));
db.open (function(error){
console.log("We are connected! " + host + ":" +port);
db.collection("stocks", function(error, collection){
console.log("We have a collection");
**var numOfDocs = db.collection('stocks').count()**
**console.log("The num of Docs in our collection is: ",numOfDocs)**
collection.find({"name":name.toString()}, function(error, cursor) {
cursor.toArray(function(error, stocks) {
if (stocks.length==0) {
//console.log("No Stocks found!");
callback(false);
}
else {
callback(stocks[0]);
//console.log("Found a stock -> ",stocks[0]);
}
});
});
});
});
}
.count() is an asynchronous function, just like .find() is.
Try the following code:
collection.count({}, function(error, numOfDocs) {
console.log('I have '+numOfDocs+' documents in my collection');
// ..
});
The first argument to .count() should be a search query. Since you want to count all documents, I'm passing an empty object {} as a search query.
Since mongo 4, count() is deprecated. You should use countDocuments() instead:
MongoDB drivers compatible with the 4.0 features deprecate their
respective cursor and collection count() APIs in favor of new APIs for
countDocuments() and estimatedDocumentCount(). For the specific API
names for a given driver, see the driver documentation.
db.orders.countDocuments({})
how do i share the db object returned from when i call db.open or db.connect across the entire app?
i have a dbconnect.js module as follows :
var mongodb = require('mongodb');
var global_db = '';
// Define options. Note poolSize.
var serverOptions = {
'auto_reconnect': true,
'poolSize': 5
};
// Now create the server, passing our options.
var serv = new mongodb.Server('localhost', 27017, serverOptions);
// At this point, there is no connection made to the server.
// Create a handle to the Mongo database called 'myDB'.
var dbManager = new mongodb.Db('myDB', serv);
// NOW we initialize ALL 5 connections:
dbManager.open(function (error, db) {
// Do something with the connection.
global_db = db;
// Make sure to call db.close() when ALL connections need
// to be shut down.
db.close();
});
function getConnection()
{
return global_db;
}
exports.getConnection = getConnection;
and i am using this dbconnect.js in my app.js as:
var http = require('http');
var db = require('./dbconnect').getConnection();
var collection = db.collection('testcollection');
console.log(db);
console.log(collection);
var server = http.createServer();
server.on('request',route);
server.listen(8000,'127.0.0.1');
console.log('Server running at http://127.0.0.1:8000');
function route(request,response)
{
var url = request.url;
var doc = {};
doc[url] = 'ok';
collection.insert(doc,{w:1},function(err,result)
{
if(err) console.log(err);
else console.log(result);
});
}
in the console, the db and collection variable show empty values, i also tried removing the db.close() call in dbconnect.js but to no use, however the insertion works when i place it inside dbconnect.js file in the dbManager.open function, how do i do this?or any similar alternatives?
You can't do that, because dbManager.open( is async method, but you trying to get data from module synchronously.
Try this:
In dbconnect.js
var on_db_ready = null;
module.exports = {
db_ready:function(db_ready_callback){
on_db_ready = db_ready_callback;
//here we call callback if already have db
if (global_db) on_db_ready(global_db);
},
getConnection:getConnection
};
dbManager.open(function (error, db) {
if (on_db_ready) on_db_ready(db);
global_db= db;
})
in app.js:
var db = require('./dbconnect').db_ready(function(db){
//Here i have my database
//or can use getConnection method
});
this is not very beautiful way, but, I hope, explain your mistake