mongodb - find() is not a function - javascript

I want to print all documents of "members" collection. I used find() function but it throw error : find() is not a function.
In member_model.js (in models/admin folder):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MemberSchema = new Schema({
username: String,
password: String
});
module.exports = mongoose.model('members', MemberSchema);
In index.js (in controllers/admin folder):
const members = require('../../models/admin/member_model');
var Members = new members();
Members.find({}, function (err, resDB) {
assert.equal(err,null);
console.log(json(resDB));
});
I checked connecting to DB, it's still ok.
I also read some other questions but any suitable answer for my problem.
Note more i tested like this :
In auth.js (in controllers/admin folder):
const members = require('../../models/admin/member_model');
var Members = new members();
Members.username = req.body.username;
Members.password = req.body.password;
var refererURL = req.headers.referer;
Members.save((err, resSave) => {
if(err) {
console.log(err);
res.redirect(refererURL);
} else {
console.log('saved');
}
})
Members.find({}, function (err, resDB) {
assert.equal(err,null);
console.log(json(resDB));
});
Members.save() is ok, but Members.find() still error.
Help me what my error is ?
Thanks!

Try the below code:
In member_model.js (in models/admin folder):
Change the below code to :
// module.exports = mongoose.model('members', MemberSchema);
module.exports = {
memberCollection: mongoose.model('members', MemberSchema)
}
In index.js (in controllers/admin folder):
const members = require('../../models/admin/member_model');
members.memberCollection.find({}, function (err, resDB) {
assert.equal(err,null);
console.log(json(resDB));
});

Related

Return value to variable from function

I am looking to return a value to a varible when I call the function in nodejs.
The output I am looking for is "Calling From Glasgow to Euston"
The output I am getting is "Calling From undefined to undefined"
Code is the following.
function trainstation(stx, callBack) {
MongoClient.connect(ttdb, function(err, db) {
if (err) throw err;
var dbo = db.db("ttdb");
var collection = dbo.collection("tlc");
var find = collection.find( { "Stanox" : stx } );
find.toArray(function(err, result) {
if (err) throw err;
db.close();
return callBack(result);
});
});
};
function gettrain(){
var ts1 = trainstation(9531, function(x){
return x[0]['Station Name'];
});
var ts2 = trainstation(31033, function(x){
return x[0]['Station Name'];
});
console.log("Calling From", ts1, "to", ts2);
};
gettrain();
Thanks :)
I don't use the MongoDB package and I don't have MongoDB up & running right now to test this, so I've written this code purely based on a quick read of the reference documentation. Perhaps you can test this and we'll fix any minor issues. Copy this code to a new source file and test it.
What I've done is to take advantage of the MongoDB package's promise features. You can see that the code is more linear and simpler to follow.
const MongoClient = require('mongodb').MongoClient;
const ttdb = 'mongodb://localhost:27017'; // or your DB URL
const trainstation = async (Stanox) => {
const client = MongoClient(ttdb);
await client.connect();
const dbo = client.db("ttdb");
const collection = dbo.collection("tlc");
const result = await collection.find({Stanox}).toArray();
client.close();
return result;
};
const gettrain = async () => {
const ts1 = await trainstation(9531);
const ts2 = await trainstation(31033);
const sn1 = ts1[0]['Station Name'];
const sn2 = ts2[0]['Station Name'];
console.log("Calling From", sn1, "to", sn2);
};
gettrain();

Mongoose nested schema

I want to make a system of topics. each topic may have subtopics which are also topics.
meaning the subtopics may also have subtopics.
for example
example image
I tried to create a topic schema and add a subtopic field which will ref to topic schema too.
cant seem to get this working my schema code:
const mongoose = require('mongoose');
const TopicSchema = new mongoose.Schema({
name: {type:String,unique:true},
sub_topic:[{type:mongoose.Schema.Types.ObjectId, ref : 'Topic'}]
});
const Topic =mongoose.model('Topic', TopicSchema);
module.exports = Topic;
Also what the data im sending to the server should look like to make a new instance?
and on the server how do i save it?
i try to save like this now :
const topic = new Topic();
topic.name = req.body.name;
topic.sub_topic.name=req.body.sub_topic
and the data im sending is :(json)
{
"name":"TestMain",
"sub_topic":[{"name":"TestSub"}]
}
UPDATE : got this done using a recursive function.
function subtopicHandler(topic, sub_topic) {
Topic.find({
"name": topic.name
}, function (err, res) {
if (err) throw err
return;
})
if (sub_topic == undefined) {
let ntopic = new Topic();
ntopic.name = topic.name;
ntopic.sub_topic == undefined;
ntopic.save(function (err, result) {
if (err) console.log('saving err', err)
});
return ntopic._id;
}
let mainTopic = new Topic();
mainTopic.name = topic.name;
sub_topic.forEach(function (sub) {
mainTopic.sub_topic.push(subtopicHandler(sub, sub.sub_topic));
})
var retME;
mainTopic.save(function (err, result) {
if (err) {
console.log('saving err', err)
throw err;
}
});
return mainTopic._id;
}
Using this schema :
const TopicSchema = new mongoose.Schema({
name: {type:String,unique:true},
sub_topic:[{type:mongoose.Schema.Types.ObjectId, ref : 'Topic'}]
});
and data sent as :
{
"name":"A",
"sub_topic":[
{"name":"C","sub_topic":
[
{"name":"C1"}
,
{"name":"C2"}
]
}
,
{"name":"B"}
,
{"name":"D","sub_topic":
[
{"name":"D1"}
,
{"name":"D2"}
,
{"name":"D3"}
]
}
]
}
to the API endpoint
handled this way:
let mainTopic = new Topic();
mainTopic.name = req.body.name;
subtopicHandler(mainTopic, req.body.sub_topic);
})
If you are sending following json
const obj = {
"name":"TestMain",
"sub_topic":[{"name":"TestSub"}]
}
Then,
let mainTopic = new Topic();
let subTopic = new Topic();
// assuming for now you have only one sub-topic in array
subTopic.name = obj[0].name;
subTopinc.save(function(err,result)=>{
if(!err){
mainTopic.name = obj.name;
mainTopic.sub_topic = [result._id]
mainTopic.save(function(err,result){
console.log(result);
})
}
});
From you schema definition and the given json you can follow the above step to get the results.
Hope this will help you.
You can do this with sub docs check out the documentation.
https://mongoosejs.com/docs/subdocs.html

Mongoose "disconnect is not a function"

I'm using this tutorial to make a node/mongo application. When I run addContact, it seems like the contact saves to the DB but, I get an error saying that the disconnect function is not a function. Can anyone tell me why this is happening and, how to fix it? I'm assume that there's some issue with the scope of the constant, db?
code:
const mongoose = require('mongoose');
const assert = require('assert');
mongoose.Promise = global.Promise;
const db = mongoose.connect('mongodb://localhost:27017/contact-manager');
function toLower(v) {
return v.toLowerCase();
}
const contactSchema = mongoose.Schema({
firstname: { type: String, set: toLower },
lastname: { type: String, set: toLower },
phone: { type: String, set: toLower },
email: { type: String, set: toLower }
});
const Contact = mongoose.model('Contact', contactSchema);
const addContact = (contact) => {
Contact.create(contact, (err) => {
assert.equal(null, err);
console.info('New contact added');
db.disconnect();
});
};
const getContact = (name) => {
const search = new RegExp(name, 'i');
Contact.find({$or: [{firstname: search }, {lastname: search }]})
.exec((err, contact) => {
assert.equal(null, err);
console.info(contact);
console.info(`${contact.length} matches`);
db.disconnect();
});
};
module.exports = { addContact, getContact };
code part2:
const program = require('commander');
const {addContact, getContact} = require('./logic');
program
.version('0.0.1')
.description('Contact management system');
program
.command('addContact <firstame> <lastname> <phone> <email>')
.alias('a')
.description('Add a contact')
.action((firstname, lastname, phone, email) => {
addContact({firstname, lastname, phone, email});
});
program
.command('getContact <name>')
.alias('r')
.description('Get contact')
.action(name => getContact(name));
program.parse(process.argv);
error:
New contact added
/Users/user/contact-manager/node_modules/mongodb/lib/utils.js:132
throw err;
^
TypeError: db.disconnect is not a function
at Contact.create (/Users/user/contact-manager/logic.js:33:8)
at Function.<anonymous> (/Users/user/contact-manager/node_modules/mongoose/lib/model.js:3913:16)
at parallel (/Users/user/contact-manager/node_modules/mongoose/lib/model.js:2077:12)
at /Users/user/contact-manager/node_modules/async/internal/parallel.js:35:9
at /Users/user/contact-manager/node_modules/async/internal/once.js:12:16
at iteratorCallback (/Users/user/contact-manager/node_modules/async/eachOf.js:52:13)
at /Users/user/contact-manager/node_modules/async/internal/onlyOnce.js:12:16
at /Users/user/contact-manager/node_modules/async/internal/parallel.js:32:13
at apply (/Users/user/contact-manager/node_modules/lodash/_apply.js:15:25)
at /Users/user/contact-manager/node_modules/lodash/_overRest.js:32:12
at callbackWrapper (/Users/user/contact-manager/node_modules/mongoose/lib/model.js:2046:11)
at /Users/user/contact-manager/node_modules/mongoose/lib/model.js:3913:16
at model.$__save.error (/Users/user/contact-manager/node_modules/mongoose/lib/model.js:342:7)
at /Users/user/contact-manager/node_modules/kareem/index.js:297:21
at next (/Users/user/contact-manager/node_modules/kareem/index.js:209:27)
at Kareem.execPost (/Users/user/contact-manager/node_modules/kareem/index.js:217:3)
mongoose.connect does not return a value, as far as I can tell from looking at the code given in the getting started guide. If you want to close the database connection, you need to call the close method on mongoose.connection which is written to when you open a connection with mongoose.connect. The simplest way to do this is to move your mongoose.connect to its own line:
mongoose.connect('mongodb://localhost:27017/contact-manager');
const db = mongoose.connection;
Then just replace your calls to db.disconnect() with calls to db.close().
Try letting mongoose handle the connection closure using mongoose.connection.close()

Querying a MongoDB based on Mongo ID in a node.js app

I'm using a node.js and mongodb, and I'm trying to query the database based on the mongo generated ID using the following:
collection.findOne( {_id:doc._id} , function(err, item) {});
I am 100% certain that my doc._id is an exact match to the doc _id that I am looking for in the collection, and yet I get a null response from the db query.
I have tried this using other keys in the document and it returns the document just fine. It's only when I try to use the mongo ID.
The MongoDb is an object not a string. To convert my string I used:
var id = require('mongodb').ObjectID(doc._id);
This converts my string into a mongo ObjectId and matches the _id in the db!
Following is the example which spots the issue:
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db,
ObjectID = require('mongodb').ObjectID;
var MongoClient = require('mongodb').MongoClient
//let id = your _id, smth like '6dg27sh2sdhsdhs72hsdfs2sfs'...
var obj_id = new ObjectID('52cbd028e9f43a090ca0c1af');
var justId = '52cbd028e9f43a090ca0c1af'; // <== This will not work
MongoClient.connect('mongodb://127.0.0.1:27017/YourDbName', function(err, db) {
console.log('err' + err);
db.collection('YourCollectionName', function(error, collection) {
//collection.find({_id:justId}),function(err, docs) { // <== This will not work
collection.findOne({_id:obj_id},function(err, docs) {
console.log("Printing docs from Array. count " + JSON.stringify(docs));
});
});
});
Use this:
ObjectId = require('mongodb').ObjectID;
Then when you try to find an object in collection by _id use this:
console.log("find by: "+ id);
database.collection("userRegister").findOne({_id: new ObjectId(id)},
function(err, res) {
if (err) console.log(err);
if(res!=null){
console.log(res)
return false;
}
if(res==null){
callback({'status':_error,'flag':'notexist','message':_userNotExist});
return false;
}
});
First we need to get ObjectID from mongodb library and need to create new instance in following way., so that you will get the ObjectID of string. If your are using es6 in your code this code
import { ObjectID } from 'mongodb';
var emQuery = [
{
$match: {
_id: new ObjectID(tlvaltResult[0].customers.createdBy)
}
},
{
$project: {
_id:1,
emailId:1,
mobile:1
}
}
];
console.log(emQuery,'emQuery');
[ { '$match': { _id: 5ad83ff0b443435298741d3b } },
{ '$project': { _id: 1, emailId: 1, mobile: 1 } } ]
var emResult = await User.getAggregation(emQuery);
console.log(emResult,'emResult');
[ { _id: 5ad83ff0b443435298741d3b,
emailId: 'superAdmin#limitlessmobile.com' } ]
First, ensure you've added all required modules in MongoDB config:
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 db = new Db('YOUR_DB_NAME', server);
Then, when you try to find an object in collection by _id, use:
//let id = your _id, smth like '6dg27sh2sdhsdhs72hsdfs2sfs'...
var obj_id = BSON.ObjectID.createFromHexString(id);
db.collection("NAME_OF_COLLECTION_WHERE_IS_YOUR_OBJECT", function(error, collection) {
collection.findOne( {_id:obj_id} , function(err, item) {
// console.log ( item.username );
});
});
Hope, this works.

node.js mongodb select document by _id node-mongodb-native

I'm trying to select a document by id
I've tried:
collection.update({ "_id": { "$oid": + theidID } }
collection.update({ "_id": theidID }
collection.update({ "_id.$oid": theidID }}
Also tried:
collection.update({ _id: new ObjectID(theidID ) }
This gives me an error 500...
var mongo = require('mongodb')
var BSON = mongo.BSONPure;
var o_id = new BSON.ObjectID(theidID );
collection.update({ _id: o_id }
None of these work. How to select by _id?
var mongo = require('mongodb');
var o_id = new mongo.ObjectID(theidID);
collection.update({'_id': o_id});
This the approach that worked for me.
var ObjectId = require('mongodb').ObjectID;
var get_by_id = function(id, callback) {
console.log("find by: "+ id);
get_collection(function(collection) {
collection.findOne({"_id": new ObjectId(id)}, function(err, doc) {
callback(doc);
});
});
}
now you can just use this:
var ObjectID = require('mongodb').ObjectID;
var o_id = new ObjectID("yourObjectIdString");
....
collection.update({'_id': o_id});
You can see documentation here
With native_parser:false:
var BSON = require('mongodb').BSONPure;
var o_id = BSON.ObjectID.createFromHexString(theidID);
With native_parser:true:
var BSON = require('mongodb').BSONNative;
var o_id = BSON.ObjectID.createFromHexString(theidID);
I just used this code in Node.js app in controller file, and it works:
var ObjectId = require('mongodb').ObjectId;
...
User.findOne({_id:ObjectId("5abf2eaa1068113f1e")})
.exec(function(err,data){
// do stuff
})
do not forget to install "mongodb" before, and if you are using encryption of your passwords with bcrypt with "presave", be sure that you will not encrypt password after each modification of the record in DB.
/* get id */
const id = request.params.id; // string "5d88733be8e32529c8b21f11"
/* set object id */
const ObjectId = require('mongodb').ObjectID;
/* filter */
collection.update({
"_id": ObjectId(id)
} )
ObjectId reports deprecated when called inside find() function in "mongodb": "^4.1.2" if the ObjectId is imported like this
const ObjectId = require('mongodb').ObjectID;
instead, when I import it with named import there is no deprecated warning
const { MongoClient, ObjectId } = require("mongodb");
then I can call it regularly
const findResult = await collection.find({_id: ObjectId(id)}).toArray();
This is what worked for me.
Using mongoDB
const mongoDB = require('mongodb')
Then at the bottom where I am making my express get call.
router.get('/users/:id', (req, res) => {
const id = req.params.id;
var o_id = new mongoDB.ObjectID(id);
const usersCollection = database.collection('users');
usersCollection.findOne({
_id: o_id
})
.then(userFound => {
if (!userFound){
return res.status(404).end();
}
// console.log(json(userFound));
return res.status(200).json(userFound)
})
.catch(err => console.log(err));
});`
The answer depends upon the variable type you are passing in as the id. I pulled an object id by doing a query and storing my account_id as the ._id attribute. Using this method you simply query using the mongo id.
// begin account-manager.js
var MongoDB = require('mongodb').Db;
var dbPort = 27017;
var dbHost = '127.0.0.1';
var dbName = 'sample_db';
db = new MongoDB(dbName, new Server(dbHost, dbPort, {auto_reconnect: true}), {w: 1});
var accounts = db.collection('accounts');
exports.getAccountById = function(id, callback)
{
accounts.findOne({_id: id},
function(e, res) {
if (e) {
callback(e)
}
else {
callback(null, res)
}
});
}
// end account-manager.js
// my test file
var AM = require('../app/server/modules/account-manager');
it("should find an account by id", function(done) {
AM.getAllRecords(function(error, allRecords){
console.log(error,'error')
if(error === null) {
console.log(allRecords[0]._id)
// console.log('error is null',"record one id", allRecords[0]._id)
AM.getAccountById(
allRecords[0]._id,
function(e,response){
console.log(response,"response")
if(response) {
console.log("testing " + allRecords[0].name + " is equal to " + response.name)
expect(response.name).toEqual(allRecords[0].name);
done();
}
}
)
}
})
});
If you use Mongosee, you can simplify the function
FindById:
this replace in mongodb: "_id" : ObjectId("xyadsdd434434343"),
example:
// find adventure by id and execute
Adventure.findById('xyadsdd434434343', function (err, adventure) {});
https://mongoosejs.com/docs/api.html#model_Model.findById
I'm using client "mongodb": "^3.6.2" and server version 4.4.1
// where 1 is your document id
const document = await db.collection(collection).findOne({ _id: '1' })
console.log(document)
If you want to copy and paste here's all you need.
const { MongoClient } = require('mongodb')
const uri = '...'
const mongoDb = '...'
const options = {}
;(async () => {
const client = new MongoClient(uri, options)
await client.connect()
const db = client.db(mongoDb)
const document = await db.collection(collection).findOne({ _id: '1' })
console.log(document)
)}()
In Mongoose, the Model.findById() function is used to find one document by its _id. The findById() function takes in a single parameter, the document id. It returns a promise that resolves to the Mongoose document if MongoDB found a document with the given id, or null if no document was found.
const schema = new mongoose.Schema({ _id: Number }, { versionKey: false });
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: 1 });
// `{ _id: 1 }`
await Model.findById(1);
// `null` because no document was found
await Model.findById(2);
When you call findById(_id), Mongoose calls findOne({ _id }) under the hood. That means findById() triggers findOne() middleware.
const schema = new mongoose.Schema({ _id: Number }, { versionKey: false });
schema.pre('findOne', function() {
console.log('Called `findOne()`');
});
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: 1 });
// Prints "Called `findOne()`" because `findById()` calls `findOne()`
await Model.findById(1);
Mongoose casts queries to match your schema. That means if your _id is a MongoDB ObjectId, you can pass the _id as a string and Mongoose will convert it to an ObjectId for you.
const _id = '5d273f9ed58f5e7093b549b0';
const schema = new mongoose.Schema({ _id: mongoose.ObjectId }, { versionKey: false });
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: new mongoose.Types.ObjectId(_id) });
typeof _id; // 'string'
// `{ _id: '5d273f9ed58f5e7093b549b0' }`
const doc = await Model.findById(_id);
typeof doc._id; // 'object'
doc._id instanceof mongoose.Types.ObjectId; // true
Source

Categories

Resources