How to get all documents of a collection with mongodb find() using webtask.io and mlab - mongodb

I have a collection named "posts" in a mongodb at mlab.com and I am trying to access all of the documents in this collection with db.collection('posts').find(). Below is my code for my webtask I've created, which I named mongodb_find:
var MongoClient = require('mongodb').MongoClient;
var waterfall = require('async').waterfall;
/**
* #param {secret} MONGO_URL - Mongo database url
*/
module.exports = function(ctx, cb) {
var MONGO_URL = ctx.data.MONGO_URL;
if (!MONGO_URL) return cb(new Error('MONGO_URL secret is missing'))
waterfall([
function connect_to_db(done) {
MongoClient.connect(MONGO_URL, function(err, db) {
if(err) return done(err);
done(null, db);
});
},
function find_hits(db, done) {
db
.collection('posts')
.find(
{},
function (err, result) {
if(err) return done( err );
done( null, JSON.stringify(result) );
}
).sort({ hits: -1 }).limit( 2 );
}
], cb);
};
I have a mongodb_upsert webtask that is very similar to this and works perfectly. However, for my mongodb_find task I am getting the following error:
{
"code": 400,
"error": "Error when JSON serializing the result of the JavaScript code.",
"details": "TypeError: Converting circular structure to JSON",
"name": "TypeError",
"message": "Converting circular structure to JSON",
"stack": "TypeError: Converting circular structure to JSON\n at Object.stringify (native)\n at /data/sandbox/lib/sandbox.js:775:48\n at /data/sandbox/node_modules/async/dist/async.js:473:16\n at next (/data/sandbox/node_modules/async/dist/async.js:5315:29)\n at /data/sandbox/node_modules/async/dist/async.js:958:16\n at /data/io/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/webtask.js:27:6\n at handleCallback (/data/_verquire/mongodb/2.0.48/node_modules/mongodb/lib/utils.js:96:12)\n at Collection.find (/data/_verquire/mongodb/2.0.48/node_modules/mongodb/lib/collection.js:354:44)\n at find_hits (/data/io/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/webtask.js:23:5)\n at nextTask (/data/sandbox/node_modules/async/dist/async.js:5310:14)"
}
When connecting to mongodb from the command line the same find() command works properly:
db.posts.find({}).sort({hits: -1}).limit(2);
The documents in the collection are set up like this:
{
"_id": {
"$oid": "5a3ff239bda4eaa4ab96ef8b"
},
"title": "Testing 6",
"url": "/jquery/2017/12/22/testing-6.html",
"hits": 2
}
Does anyone know of a solution to this issue? Thank you.

Collection.find returns a cursor, not the results of the query. You probably want to chain all your operations such as sort and limit on the cursor, then use toArray to define the callback. toArray will retrieve the results from the cursor.
For example:
function find_hits(db, done) {
db.collection('posts')
.find({})
.sort({ hits: -1 })
.limit(2)
.toArray(function (err, result) {
if(err) return done( err );
done(null, JSON.stringify(result));
});
}

Related

Unable to order by with allDocs in PouchDB

I'm unable to order the result set returned from the allDocs function in PouchDB.
db.allDocs({startKey: "cat_", include_docs: true, orderBy: "category_name"}, function(err, response) {
if (err) return console.log(err);
allCategories = response.rows;
});
I also tried to use sort instead of orderBy but it didn't work.
This is the structure of my documents:
db.put({
"_id": "cat_5601",
"category_name": "Groceries",
"parent_category": null,
"category_vat": 1,
});

Mongodb.com how to confirm if a collection is correctly setup as a Time Series Collection?

I try to create a Time Series Collection on Mongodb.com like this:
//create timeseries collection with expiry
MongoClient.connect(uri, function(err, client) {
if (err) throw err;
var db = client.db("abc");
db.createCollection("events",{
timeseries: {
timeField: "timestamp",
metaField: "metadata",
granularity: "seconds"
},
expireAfterSeconds: ...
}, function(err, res) {
if (err && err.codeName != "NamespaceExists") {
console.log("error creating collection", err.codeName)
console.log("error creating collection", res)
}else{
console.log("Collection events created!", res);
}
collection = db.collection("events");
console.log("collection", collection);
});
});
//insert timeseries data
var date = moment.utc(json.created_date).toDate();
var data = {
"metadata": json,
"timestamp": date,
"price": price
}
const insertResult = await collection.insertOne(data);
I can that a collection is created and data is increasing. But I remember last time Mongodb.com will show "time series" label somewhere near the collection overview page, but now I don't see it anymore. There is no way for me to confirm if this collection is correctly configured as a Time series collection? How can I confirm?
const collectionName = "events";
db.getCollectionInfos({name:collectionName}, {nameOnly: true });
above code should give you the name and type of your collection "events"
reference - https://www.mongodb.com/docs/manual/reference/method/db.getCollectionInfos/#example
https://www.mongodb.com/docs/manual/core/timeseries-collections/#check-if-a-collection-is-of-type-time-series

Change type of value in collection using update

I am looking for a way, how to update multiple documents in MongoDB. I want to modify similar structure like this one:
{[
"_id": 'mongo_id',
"name": "Name"
]}
to the structure like this, basically just change string attribute to object attribute with string property :
{
"_id": 'mongo_id',
"name": {
"type_1": "Name",
"type_2": ""
}
}
Is there a way how to do it in single mongo query or I have to create some kind of worker for example in node.js?
If you do not have any schemas involved to put constrains on your collections or if you have and name is defined as mixed type (from mongoose types as an example) then you can do whatever you want to any of the properties other than _id.
for example this update will change name to the object you want:
db.getCollection('<collectionName>').update({
_id: "mongo_id")
}, {
name: {
"type_1": "Name",
"type_2": ""
}
})
It looks like the best solution is create little worker to get all documents and update them in collection. I used node.js and mongodb npm package to create worker similar to this one:
var mongo = requiere('mongodb');
mongo.connect(process.env.MONGO_URL, function(err, database) {
if (err) {
throw err;
}
db = database;
db.collection('<collectionName>').find({}).toArray(function(err, array) {
if (err) {
console.log(err);
return process.exit(1);
}
console.log('length:', array.length);
var promises = [];
array.forEach(item => {
promises.push(db.collection('<collectionName>').update(
{
_id: item._id
},
{
'$set': {
'name': {
'type_1': item.name,
'type_2': '',
}
}
}))
});
return Promise.all(promises).then(function() {
console.log('Done');
return process.exit(0);
}).catch(function(err) {
console.log('err:', err);
return process.exit(1);
});
});
});

Mongoos Add dynamic columns Error

I want to add dynamic columns in my document but when add new column
it display error, I m using mongoDB 3.4
router.post('/get-personal-information', function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
Employee.update({_id : req.body._id},{$set:{'name1' : 'dsadas'}}, {upsert:true}, function(err, doc){
if (err) return res.send(500, { error: err });
return res.send(doc);
});
});
Error Message ::
{
"error": {
"name": "MongoError",
"message": "'$set' is empty. You must specify a field like so: {$set: {<field>: ...}}",
"driver": true,
"index": 0,
"code": 9,
"errmsg": "'$set' is empty. You must specify a field like so: {$set: {<field>: ...}}"
}
}
i found the solution
Use {strict: false} to modify the columns or make any type of
operation on columns
router.post('/get-personal-information', function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
Employee.update({_id : req.body._id},{$set:{'name1' : 'dsadas'}}, {strict:false}, function(err, doc){
if (err) return res.send(500, { error: err });
return res.send(doc);
});
});

mongo always returns null even though data is available

i have insert few docs into my mongodb and while fetching i am always getting null as reponse
this is my get method
router.get('/getPersonDetails/:id', function(req, res) {
var db=req.db;
var collection=db.get('Person');
var reqId = req.params.id;
var query={'person_id':reqId}
console.log(query);
collection.findOne(query, function(err, item) {
console.log(item);
res.send(
(err===null) ? {msg:item} : {msg:err}
);
});
});
this is the add method
router.post('/addPerson', function(req, res) {
var db = req.db;
var collection = db.get('Person');
collection.insert(req.body, function(err, result) {
res.send(
(err===null) ? {msg:result} :{msg:err}
);
});
});
had create db in the same hierarchy that my node project exists.
MySample out out when i tried in getAll API;
0: {
"_id": "56b1ac863a9ac81c4177fbfc"
"{ "person_id": "1", "person_name": "gvsharma" }": ""
}
i think am missing something here?
i am a new learner. and please correct me where am wrong?
If your query is running on this document, then query you have specified will not work. The inserted format is incorrect.
This is your data:
{
"_id": "56b1ac863a9ac81c4177fbfc",
"{ "person_id": "1", "person_name": "gvsharma" }": ""
}
This is how it should be inserted:
{
"_id": "56b1ac863a9ac81c4177fbfc",
"person_id": "1",
"person_name": "gvsharma"
}
that query will work on above document. Please check the insert query you are not getting JSON in format that you are expecting when you read req.body.