I am new to Mongoose and I can't figure out how to get the results of my database from mlab.
I know how to findOneAndUpdate, but I am having trouble getting the results. The Mongoose site, I feel is not as informative as it could have been in terms of explaining how to get a particular result.
My MongoDB database looks something like this. The name of the collection is TagstoFiles.
I want to use Mongoose to put return all file_id's for a given tag.
I could not understand how to use findOne and findById from mongoose's site.
I tried writing some code but to no avail.
router.post('/decrypt_download', ensureAuthenticated, function(req, res){
var tags = req.body.ea;
var arrayOfFiles = [];
TagstoFiles.findOne({tag:tags[0]},function(err, file_id){
var obj = JSON.parse(file_id);
});
//how to use ^
res.send("Working.");
});
Can someone please explain how to accomplish this?
Here i explain how to use findOne and findById find usage its the same , to do what i understand you want you need to use find
var Wanted= require('../models/wanted');
Wanted.findOne({"idsearch":idofwantedele, "secondparam":otherfilter}).exec((err,result) =>{
if (err) return res.status(500).send({message : "something for an error"});
if (result ) {
return res.status(200).send({message: "here the result has the object of type wanted"});
}
if (!result ){
return res.status(400).send({message : "nothing with those filters"});
}
});
findById
var Wanted= require('../models/wanted');
Wanted.findById(wantedid, (err, result) => {
if(err) return res.status(500).send({message : "something for an error"});
if(!result) return res.status(404).send({message : "nothing with those filters"});
if(result) return res.status(200).send({message:"result is a wanted with wantedid"});
});
Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WantedSchema = Schema({
some: String,
secondparam:String,
reftootherschema: { type: Schema.ObjectId, ref: 'User' },
});
module.exports = mongoose.model('Wanted',WantedSchema);
Related
I have created a sigle app with a Schema and a Model to create a Collection and insert some Documents.
I have my todoModel.js file:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const todoSchema = new Schema({
username: String,
todo: String,
isDone: Boolean,
hasAttachment: Boolean
});
const Todos = mongoose.model("Todo", todoSchema);
module.exports = Todos;
Then I have created a setUpController.js file with a sample of my Documents. Then I create a Model and I pass my sample of Documents and my Schema. I create a response to send tje result in JSON.
Everything good here, as I get the result in json when accessing to the route.
Here is the code:
Todos.create(sampleTodos, (err, results) => {
if (!err) {
console.log("setupTodos sample CREATED!")
res.send(results);
}
else {
console.log(`Could not create the setupTodos Database sample, err: ${err}`);
}
});
My problem is that this Documents don´t get saved in the collection !! When I access to the database, nothing is there.
This is my app.js file:
mongoose.connect("mongodb://localhost:27017/nodeTodo")
.then(connection => {
app.listen(port);
})
.catch(err => {
console.log(`Could not establish Connection with err: ${err}`);
});
Could anyone help me please ?
Thank you
Try creating an instance and making the respective function call of that instance. In your case, save the document after creating an instance and it works like a charm.
const newTodos = new Todos({
username: "username",
todo: "todos",
isDone: false,
hasAttachment: flase
});
const createdTodo = newTodos.save((err, todo) => {
if(err) {
throw(err);
}
else {
//do your staff
}
})
after the collection is created you can use the function inserMany to insert also a single document the function receives an array of objects and automatically saves it to the given collection
example:
Pet = new mongoose.model("pet",schemas.petSchema)
Pet.insetMany([
{
//your document
}])
it will save only one hardcoded document
I hope it was helpful
The problem is probably simple, but my 2 AM brain can't understand what's going on anymore. I'm trying to create a profile page that shows basic public info. The way I'm trying to make it work is pulling out the users username from mongodb when registered the account by his specific _id. If needed, verification I use is JWT.
app.post('/api/user-profile', async (req,res) => {
const { token } = req.body
if(!token) {
return res.json({ status: 'error', error: 'not logged in' })
}
try {
const user = jwt.verify(token, JWT_SECRET)
const userid = user.id
const result = User.findOne({ userid })
console.log(result)
// return res.json({ status: 'ok', name: result })
} catch(error) {
// return res.json({ status: 'error', error: 'something went wrong' })
console.log(error)
}
})
I'm not sure what function should I use, findOne() or findById(). I tried to look at the documentation at mongoose, but the explanation is a bit too hard for me to understand.
P.S User = the user registration model. If needed I can paste in the code.
use findById instead of findOne if userid is _id and use await before the query, so do like this:
const result = await User.findById(userid)
if you want to use findOne :
const result = await User.findOne({"_id" : userid})
if you want a plain object javascript use .toObject after query like this:
const result = await User.findById(userid).toObject()
console.log(result)
I don't have a lot of experience with mongoose but worked with Mongo quite a lot. findOne is a direct correspondent of Mongo's findOne function which receives a query in the format {"key": "expectedValue"}. If you want to use it to get data by id the query is {"_id": user.id}.
Because fetching data by id is a common case, the lib added the method findByID which receives an ID, and then formats the query and makes an internal call to findOne.
For anyone interested, the answer is just like Mohammad Yaser Ahmadi said. Everything works fine, and by getting the username I did:
const user = jwt.verify(token, JWT_SECRET)
const userid = user.id
const result = await User.findById(userid)
const usersName = result.username
console.log(usersName)
I am trying to make a search api using nodejs and MongoDB. I tried to google about this and I did find something there but while trying to implement I get an error saying. I don't know how to fix this honestly I don't know anything about making search API. So any help or suggestion will be helpful for me.
This is the link of the post I found on google Building a simple search api.
error
{
"error": {
"message": "Cast to ObjectId failed for value \"search\" at path \"_id\" for model \"Post\"",
"name": "CastError",
"stringValue": "\"search\"",
"kind": "ObjectId",
"value": "search",
"path": "_id"
}
}
This is my code
postController.search = (req, res) => {
var response = [];
if(typeof req.query.title !== 'undefined'){
db.Post.filter(function(post) {
if(post.title === req.query.title){
console.log(req.body);
response.push(post);
console.log(post);
}
});
}
response = _.uniqBy(response, '_id');
if(Object.key(req.query).length === 0){
response = db.Post
}
res.json(response);
};
data in the collection
"data": [
{
"isDeleted": false,
"_comments": [],
"_id": "5d39122036117d2ea81b434c",
"title": "facebook post",
"link": "facebook.com",
"_creator": {
"createdAt": "2019-07-25T01:42:21.252Z",
"username": "adityakmr"
},
"createdAt": "2019-07-25T02:21:20.634Z",
"__v": 0
},
]
If you're trying to create an API to search mongoDB collection based on title i.e; a text field try implementing text search feature of mongoDB : text search in mongoDB
, Just create a text index on title field & then create an API with post method which takes in parameter that can be queried against title field.
Text search can be a bit tricky it can help you for fuzzy/partial/full text searches - use of regex is also much beneficial.
Checkout links for node.js API example :
MongoDB NodeJs Docs
Full Text Search with MongoDB & Node.js
Text Searching with MongoDB
First of all, you need to use async/await for modularize your code. I suggest don't write your whole code in your controller.js file, API can be made by following the way (routes - controller - utils ).
postRoutes.js
postRouter.get('/search-post', postCtr.searchPost);
postController.js
const postUtils = require('./postUtils');
const postController = {};
postController.searchPost = async (req, res) => {
try {
const { title } = req.query;
const result = await postUtils.searchPost(title);
return res.status(200).json(result);
} catch (err) {
return res.status(err.code).json({ error: err.error });
}
};
module.exports = postController;
postUtils.js
const Post = require('./postModel');
const postUtils = {};
postUtils.searchPost = async (title) => {
try {
let result = [];
if(title){
// Even you can perform regex in your search
result = await Post.find({ title: title });
}
return result;
} catch (err) {
const errorObj = { code: 500, error: 'Internal server error' }; // It can be dynamic
throw errorObj;
}
};
module.exports = postUtils;
postModel.js
const mongoose = require('mongoose');
const postSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
required: true,
},
// Your fields ...
}, { collection: 'post', timestamps: true });
const post = mongoose.model('post', postSchema);
module.exports = post;
Using this structure you can easily debug your code and It's also manageable.
In the link you specified above, they are using array of objects stored in file called store.js, but not mongoDB. So directly they are filtering using Array.filter method.
But in mongoDB using mongoose(object modeling tool) you can make use of collection.find() method.
So solution to your problem is as follows
postController.search = async (req, res) => {
var response = [];
if (req.query.title) {
response = await db.Post.find({title: req.query.title});
}
res.json(response);
};
find is inbuilt query method which helps in querying the collections, you can pass multiple properties for querying.
In my app, I do return promise with my mongoose model:
var roomModel = require('../../../models/room').roomModel;
roomModel.findOne({ name: req.body.roomName })
.then(
(room) => {
return new Promise(function(resolve, reject) {
//if no room present, create one, if present, check password
if (room) {
if (room.password === req.body.roomPassword) {
return resolve(room);
} else {
return reject({
code: 401,
message: 'Room password not correct'
});
}
} else {
// create new room with given data
var newRoom = roomModel({});
newRoom.name = req.body.roomName;
newRoom.password = req.body.roomPassword;
//newRoom.users = [];
newRoom.users[0] = {
name: req.body.userName
};
newRoom.save()
.then((data) => {
console.log(data);
if (!data) {
return reject({
code: 500,
message: 'Error when saving room'
});
} else {
return resolve(newRoom);
}
});
}
});
}
)
.then((room) => {
room.findOne({ 'users.name': req.body.userName })
.then((user) => {
console.log(user);
});
})
room.js model:
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = require('./user').userSchema;
var room = new Schema({
name: String,
password: String,
users: [userSchema]
});
module.exports.roomSchema = room;
module.exports.roomModel = mongoose.model('room', room);
users.js model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user = new Schema({
name: String
});
module.exports.userSchema = user;
module.exports.userModel = mongoose.model('user', user);
but when I try to call .findOne() function on this returned model, I get following error:
TypeError: room.findOne is not a function
is model passed in the promise not a model in next .then() statement?
Found problem by myself: I was passing not the model, on which I can use find operations, but document, on which I can perform save options (not find, since it's not a model).
Well, as the docs say "queries are not promises".
There's even a findOne() example in there...
Change your code to
roomModel.findOne({ name: req.body.roomName }).exec().then(/* your stuff */)
and you may have more luck.
You missed out exec() method in your query, try to use and get resolved.
roomModel.find({ name: req.body.roomName }).exec().then(/* your stuff */)
I should think what you're doing is dangerous. Calling a queries then() multiple times might
lead to multiple query calls.
https://mongoosejs.com/docs/queries.html#queries-are-not-promises
Also, there is no need to do exec().then(). Just calling then() executes the query; a better way to use exec() is to actually pass a callback to it.
in my case it happened that no matter how I exported it it wasn't working, and I found this solution:
var {roomModel} = require('../../../models/room')
Put the import within {}
and export it normally, i do like this:
var room = mongoose.model('room',roomSchema);
module.exports.room = room;
I'm using a MEAN stack and writing these methods in Mongoose. I'm wondering what's wrong with what I put in the Mongoose model file. I would like to use Mongoose to simply print out a list all the documents in the myModel collection.
myModel.methods.myMethod = function(cb){
this.model("Bids").find({}, 'myField', function(err, results){
if (err){console.log(err);return err;}
console.log("okay");
console.log(results);
})
this.save(cb);
}
Also, what is the code that I can write in Mongoose to tell if the myModel collection is empty or not?
It's better to teach a man how to fish than to give him a fish ...
So it would be extremely helpful if you can suggest what debugging tools I can install, such as an Express middleware, that can help me debug myself. Please post your debugging suggestions here.
I'm assuming every other setup required for mongoose is correct.
At the line below, I think 'myField' is not needed.
this.model("Bids").find({}, 'myField', function(err, results)
Here is something more from scratch, maybe it would help you to trace-back you steps:
var mongoose = require('mongoose');
//connection to Mongodb instance running on=======
//local machine or anywhere=========================
var uri = 'mongodb://localhost:27017/test';
var connection = mongoose.createConnection(uri);
//Define Schema==================================
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
author: { type: Schema.Types.ObjectId },
title: String,
body: String
});
//Create model===================================================
var BlogPostModel = connection.model('BlogPost', BlogPostSchema);
//function to insert doc into model NOTE "pass in your =======
//callback or do away with it if you don't need one"=========
var insertBlogPost = function (doc, callback) {
//here is where or doc is converted to mongoose object
var newblogPost = new BlogPostModel(doc);
//save to db
newblogPost.save(function (err) {
assert.equal(null, err);
//invoke your call back if any
callback();
console.log("saved successfully");
});
};
//function to get all BlogPosts====================================
var getAllBlogPosts = function (callback) {
//mongoose get all docs. I think here answers your question directly
BlogPostModel.find(function (err, results) {
assert.equal(null, err);
//invoke callback with your mongoose returned result
callback(results);
});
};
//you can add as many functions as you need.
//Put all of your methods in a single object interface
//and expose this object using module.
var BlogPostManager = {
insertBlogPost: insertBlogPost,
getAllBlogPosts : getAllBlogPosts
}
module.exports = BlogPostManager;