MongoJS: size() method or length not available - node.js

I just installed the latest versions of node.js and MongoDB and a driver for node.js: MongoJS
Now I tried to find out (with good performance due a high load app) if a record exists in the database. I tried this query but all I get is an error:
var query = db.users.find({ nickname: 'test' }).limit(1);
console.log(query.size());
// or also
// console.log(query.length);
// => undefinied
Error:
TypeError: Object [object Object] has no method 'size'
Via console.log(typeof query) I just get object.
If I just log query I get this:
{ _readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: false,
calledRead: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
objectMode: true,
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null }
readable: true,
domain: null,
_events: {},
_maxListeners: 10,
_get: [Function] }
I get all the time this as result, even if the item exists or not.

I don't see any mention of a size method in the current docs. Instead, while count would also work here, you could use findOne to do this:
db.users.findOne({ nickname: 'test' }, function(err, doc) {
if (doc) {
// At least one matching doc exists
} else {
// No match found
}
});

Related

MongoDB: Log a random record from collection to the console

I am using mongodb atlas and node.js. I am trying to retrieve a random record from my collection "personal_information". it seems as though I should used use :
db.collection("personal_information").aggregate([{ $sample: { size: 1 } }]);
but I am unsure as to how to log the result onto the console.
Any ideas?
UPDATE
this is what the entire section looks like
const findCustomer = function(db, callback) {
db.collection("personal_information").aggregate([{ $sample: { size: 1 }
}], function(err, data) { console.log(err, data) })
}
however the this is a snippet of what is logged to the console:
AggregationCursor {
_readableState: ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: false,
errored: null,
closed: false,
closeEmitted: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},

MongoDB find an element on NodeJS returning an object

I'm working with the MongoClient and it would seem that whenever I try to find by query, I get an object back in return, but it works perfectly fine in the mongo terminal. This database initialization works for inputting data.
MongoDB terminal:
mongo
use player-db
db.players.find({"id":"1"})
Result: { "_id" : ObjectId("5f3ca631950b2f4b1f157e27"), "id" : "1", "name" : "test" }
And now in server.js:
const url = '{ommited}'
const dbName = 'player-db'
let db;
MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }, (err, client) => {
if (err) return console.log(err)
db = client.db(dbName)
console.log(`Connected to Database: \n ${url}/${dbName}`)
})
/** Function that isn't working **/
const GetOne = (collection, id) => {
let test = db.collection("players").find({"id" : "1"});
console.log(test);
}
Expected output:
{ "_id" : ObjectId("5f3ca631950b2f4b1f157e27"), "id" : "1", "name" : "test" }
Actual output:
Cursor {
_readableState: ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: false,
errored: false,
closed: false,
closeEmitted: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
........................... etc.
You are currently getting and logging the cursor.
let test = db.collection("players").find({"id" : "1"}).toArray(function(err, docs) {
console.log(docs)
});
Should display your docs. toArray will "convert" the cursor to an array of found documents. It accepts a callback function that it will execute when it is complete. You could also you promises or async/await await db.collection...

Nodejs stream with braintree?

I am trying to build an api route for a transaction, I want to grab the transaction details from the braintree server.
My app is setup so that the braintree customerId() is the same as the ID as my app user. So below I search for all the transactions for a particular user logged in.
Meaning req.user.id will always equal customerId() which sits on the braintree server.
app.get('/project', function(req, res) {
if(req.user) {
// Finds all transactions for a particular customer
var stream = gateway.transaction.search(function (search) {
search.customerId().is(req.user.id);
});
console.log(stream);
//res.send(stream);
}
});
I want to return the details, but the stream looks like below. So obviously this makes me think that there is a certain way to handle a node stream?
I have seen things like readable-stream, I am not sure if that is what I need to handle this stream object.
My question is how do I handle the stream object to return the details of the transaction?
{ _readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: false,
calledRead: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
objectMode: true,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: {},
_maxListeners: 10,
searchResponse: { stream: [Circular], success: true },
currentItem: 0,
currentOffset: 0,
bufferedResults: [] }
This returned the transaction data. I am going to keep looking into node streams, and am open to making this better, but as of now it at least returns the data.
stream.on("data", function (data) {
res.json(data);
});
This gives me an error though Error: Can't set headers after they are sent.
I think stream.pipe(res) should work.
The reason you were getting that "can't set headers after they are sent" error, is because the streams 'data' event was emitted multiple times, so you were trying to call res.json multiple times for the same request.

Nodejs request socket object parameter

Sorry if I ask silly question, I am working with the example below regarding on nodejs long polling.
http://www.stoimen.com/blog/2010/12/02/diving-into-node-js-a-long-polling-example/
I understand most of them, but just one thing I am not quite able to understand although I have done thousands of searching.
fs.stat('filepath', function(err, stats) {
// if the file is changed
if (stats.mtime.getTime() > request.socket._idleStart.getTime()) {
// read it
fs.readFile('filepath', 'utf8', function(err, data) {
// return the contents
response.writeHead(200, {
'Content-Type' : 'text/plain',
'Access-Control-Allow-Origin' : '*'
});
// return response
response.write(data, 'utf8');
response.end();
// return
return false;
});
}
});
The part "request.socket._idleStart", what is the meaning of the parameter _idleStart? Actually, I try to print out the whole request object and got the following parameters.
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: false,
calledRead: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: {},
_maxListeners: 10,
socket:
....
...
...
I am wondering if there is any documentations describing these parameters, thanks for all for the help!
those parameters with _ underscore, are used for maintaining the state of socket, its not meant for working with them. there are functions that are more reliable than those.
from node.js documentation
readable._read
Note: This function should NOT be called directly. It should be
implemented by child classes, and called by the internal Readable
class methods only.
All Readable stream implementations must provide a _read method to
fetch data from the underlying resource.
This method is prefixed with an underscore because it is internal to
the class that defines it, and should not be called directly by user
programs. However, you are expected to override this method in your
own extension classes.

How do I store a mongojs query result to a variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
All i get from this code:
var views = db.books.find({"number":1}, {"views":1, _id:0});
console.log(views);
is this response:
{ _readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: false,
calledRead: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
objectMode: true,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: {},
_maxListeners: 10,
_get: [Function] }
You can use .findOne to return a single instance and get the result.
Find assumes you're querying for a collection of documents and return a cursor:
You can for example, convert it to an array:
db.books.find({"number":1}, {"views":1, _id:0}).toArray(function(err, results){
console.log(results);
});
You can use .each to iterate through elements and .nextObject to get the next, they're all asynchronous obviously being IO operations in nodejs, here is the section on cursors in the manual.

Resources