I'm trying to add in my first plugin - mongoose-text-search.
https://npmjs.org/package/mongoose-text-search
I'm getting the error: How to Error: text search not enabled that I can't figure out.
I have my schema in seperate file where it gets compiled into a model that I export. (Works fine.)
blogSchema.js
var mongoose = require('mongoose');
var textSearch = require('mongoose-text-search');
var blogSchema = new mongoose.Schema({
title: String,
author: String,
}],
});
// give our schema text search capabilities
blogSchema.plugin(textSearch);
var Blog = mongoose.model('Blog', blogSchema);
exports.Blog = Blog;
This is relevant code for the server side. When the client sends a request to /search/,
the socket hangs up - Got error: socket hang up and on the server side I get the
How to Error: text search not enabled message.
server.js
var express = require('express')
, mongoose = require('mongoose')
, textSearch = require('mongoose-text-search');
var search_options = {
project: 'title -_id'
};
app.get('/search', function (req, res) {
console.log("inside text search");
Reading.textSearch('writing', search_options, function (err, output) {
if (err) throw err;
console.log(output);
});
});
Thanks.
You need to enable text search on the MongoDB server as described here as it's disabled by default.
Related
I'm building a cafe website with NodeJS, Express, and Mongo. I'm attempting to create a new cafe in one of my routes with a get request using a model I created. However, I keep getting an TypeError in my terminal stating that Cafe is not a constructor. I don't understand because I have defined the Schema in a separate file and I've included it in my app.js (routes file). Any feedback about this error is appreciated. I've included a few photos along with the code. Thank you in advance!
const path = require('path')
const mongoose = require('mongoose');
const Cafe = require("./models/cafe");
mongoose.connect('mongodb://localhost:27017/cafe-hopping', {
useNewURLParser: true,
useUnifiedTopology: true
})
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
console.log("Database connected");
});
const app = express()
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'))
app.get('/createcafe', async(req, res) => {
const cafes = new Cafe ({ name: 'Cueva Matera', description: "A cave like theme cafe"});
await cafes.save();
res.send(cafes)
})
*The following is the Schema (the file name is cafe.js)*
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CafeSchema = new Schema({
name: String,
price: String,
description: String,
location: String
});
module.export = mongoose.model('Cafe', CafeSchema);
[![app.js file. This is where I am keeping all of my routes][1]][1]
[![cafe.js file. This is where I create a new Schema for the database][2]][2]
[![This is the server error message I'm getting in my terminal every time I send the /createcafe get request][3]][3]
[1]: https://i.stack.imgur.com/mgTYg.png
[2]: https://i.stack.imgur.com/p9Ibx.png
[3]: https://i.stack.imgur.com/hFzzJ.png
The issue appears to be that you should be using
module.exports = mongoose.model('Cafe', CafeSchema);
Instead of module.export
Because of the misnamed property (export vs exports) the schema is not getting exported correctly, and Cafe is not a constructor.
edit: added image of collection
edit2: after a few debugging, i tried to save a document and run the find() query, and it worked (i found the test document i saved). i think the problem now is somewhere in the connection to the db. i may be connecting to somewhere else
edit3 changed title because it doesnt seem to point to the actual problem.
after a few debugging, i found out that mongoose is querying to somewhere else aside from the database i specified in uri. when i tried to save a test document, it was saved successfully and i was able to get it back using find(). However when i used find(), it only returned the previously saved test document. So now im wondering where are these documents saved?
to add more details, here are some of the codes ive written:
apiServerRoutes.js
'use strict';
module.exports = function(app) {
var apiServer = require('../controllers/apiServerControllers');
app.route('/items')
.get(apiServer.get_all_item);
app.route('/items/:itemId')
.get(apiServer.get_item);
};
apiServerControllers.js
'use strict';
var mongoose = require('mongoose');
var Item = mongoose.model('item_m');
exports.get_all_item = function(req, res) {
console.log("get_all_item() is called");
Item.find({}, function(err, item) {
if (err)
res.send(err);
res.json(item);
});
};
exports.get_item = function(req, res) {
console.log("get_item() is called");
Item.findOne({item_typeId: req.params.typeId}, '',function(err, item) {
if (err)
res.send(err);
res.json(item);
});
};
ItemSchema.js
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ItemSchema = mongoose.Schema({
item_name: String,
item_desc: String,
item_type: String,
});
var Item = mongoose.model('item_m', ItemSchema, 'item_m');
module.exports = Item;
server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Item = require('./api/models/ItemSchema'),
bodyParser = require('body-parser');
mongoose.Promise = global.Promise;
mongoose.set('debug', true);
mongoose.connect('mongodb+srv://[[user]]:[[pass]]#market-test-app-1dza9.mongodb.net/test?retryWrites=true&w=majority', {
useNewUrlParser: true, useUnifiedTopology: true});
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("Connection Successful!");
});
var routes = require('./api/routes/apiServerRoutes');
routes(app);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(port);
console.log('RESTful API server started on: ' + port);
end of edit3
the stuff below this are from the original question i had before i did some digging and debugging
So I have this controller function which uses a simple find query with no projection parameters
exports.get_all_item = function(req, res) {
Item.find({}, function(err, item) {
if (err)
res.send(err);
res.json(item);
});
};
Everytime I run my request in postman, I get an empty result. When I turned debug mode on in express, I saw this query sent by mongoose
Mongoose: item_m.find({}, { projection: {} })
When I try to run this query in mongodb, i get this error
"message" : ">1 field in obj: {}",
If I do add a parameter for projection eg. item_name, mongoose sends this:
Mongoose: item_m.find({}, { projection: { item_name: 1 } })
and when run that query in mongodb, i get this error
"message" : "Unsupported projection option: projection: { item_name: 1.0 }",
But when I change the query to
db.item_m.find({}, { item_name: 1 } )
It works fine, returning the results that Im expecting.
Im still new to both express, node.js, and mongodb. Is this some version problem between mongodb and mongoose?
Im using 4.0.13 for mongodb and 5.8.3 for mongoose but from what I researched, this should be fine. What other stuff am I missing here? Or what ever stuff should I check into that I may have missed?
Thanks in advance.
I use fetch all query using this method. I have tweaked it for your need.
exports.get_all_item = (req, res, next) => {
Item.find()
.select("item_name")
.exec()
.then(items => {
if (items.length > 0) {
res.status(200).json(items);
} else {
res.status(204).json({
message: "No items available"
});
}
})
.catch(error => {
next(error);
});
};
Hope it helps :)
When I checked back in my DB using mongodb atlas, I found that there were two existing databases: master (where I keep my data) and test (im not sure how this was created, but it existed). The entire time mongoose was accessing test and not master. I changed the 'test' in my URI to 'master' and it worked fine.
So I guess the lesson here is to double check the URI; and when debugging, try saving a sample data and find where that data is saved.
I'm writing an Node.js REST API using express web server and mongoDB as DB server.
The project's directory tree is the following :
https://i.stack.imgur.com/LFWGt.png
When I try to access "/new/test" route, I'm getting the error "Cannot GET /new/test". By accessing this path it should create an new entry into the DB based on "firstname" URL parameter.
Routes.js :
'use strict';
module.exports = function(app) {
var americaine = require('../controllers/americaineController');
// Firstname Routes
app.route('/new/:firstname')
.post(americaine.new_firstname);
};
DB entry creation function is located on Controller.js :
'use strict';
var mongoose = require('mongoose'),
Firstname = mongoose.model('Firstname');
exports.new_firstname = function(req, res) {
var new_firstname = Firstname(req.params.firstname);
new_firstname.save(function(err, firstname) {
if (err)
res.send(err);
res.json(firstname);
});
};
Model.js :
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var FirstNameSchema = new Schema({
/*id: {
type: Number,
required: false
},*/
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Firstname', FirstNameSchema);
Do you guys have any ideas about my issue ? Thanks in advance.
Jérémy
change the method .post() to .get()
since you're actually doing a get request and not a post request.
I am trying to insert a sub document into all existing documents in a collection in db,in nodejs using express framework.Following is the code snippet:
updatedoc: function(update,options,cb)
{
return this.update({},update,options).exec(cb);
}
where parameters update and options are as follows :
const update = { $push: { "defaultads": content }};
const options = { multi: true};
It seems to run and gives the following output on the console :
{ n: 1, nmodified: 1, ok: 1 }
but no push takes place at all ,in any of the documents of the database.
I have checked :
1) whether i am pushing in the right db.
2) whether correct values are being passed
However I am not able to find where I am going wrong.
I am new to nodejs and would really appreciate guidance in solving this problem.
Thanks in advance.
I am giving a simple code with full fledged requirement of yours. First create a config.js using this file you will be connected to mongodb.Here is the code
module.exports = {
'secretKey': '12345-67890-09876-54321',
'mongoUrl' : 'mongodb://localhost:27017/product'
}
Next create a models folder . Keep this schema in this models folder . I named it as product.js. Here is the code
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var imageSchema = new Schema({
imagepath:{
type:String
}
});
var nameSchema = new mongoose.Schema({
productName:{type: String},
productPrice:{type: Number},
imagePaths:[imageSchema]
});
module.exports = mongoose.model("product", nameSchema);
Next create a routes folder and keep this routes code in this folder I named it as route.js. Here is the code
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var Product = require('../models/product');
var app = express();
var Router = express.Router();
Router.use(bodyParser.json());
Router.get('/product',function(req,res){
Product.find({}, function (err, product) {
if (err) throw err;
res.json(product);
});
})
Router.post('/productData',function(req, res, next){
Product.create(req.body, function (err, product) {
if (err) throw err;
console.log('Product Data created!');
var id = product._id;
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Added the product data with id: ' + id);
});
})
Router.post('/subdocument',function (req, res, next) {
Product.find({},function (err, result) {
if (err) throw err;
for(var i=0;i<result.length;i++){
result[i].imagePaths.push(req.body);
result[i].save(function (err, ans) {
if (err) throw err;
console.log('SubDocument created!');
});
}
res.send("Successfully added");
});
})
module.exports = Router;
Next server code I named it as app.js. Here is the code
var express = require('express');
var bodyParser = require('body-parser');
var Product = require('./models/product');
var mongoose = require('mongoose');
var config = require('./config');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log("Connected correctly to server");
});
var app = express();
var route=require('./routes/route');
app.use('/route',route);
app.listen(3000,function(){
console.log("Server listening on 3000");
});
Run the server as node app.js.
API's
Use GET method http://localhost:3000/route/product .This is for getting all the product information.
Use POST method http://localhost:3000/route/productData .This for creating document. Post data in json format through request body like
{
"productName" : "sweets",
"productPrice" : "33"
}
You will see the response like this.
First post some documents i.e., post 2 or 3 documents and then you can see the documents with get API as I mentioned above. Then you will see all the documents contains empty sub document. You will see the response like this
And now add the sub document to all using the below api.
Use POST method http://localhost:3000/route/subdocument . Using this you can add a sub document to all the documents like this you need to add sub document
{
"imagepath" : "desktop"
}
You can see the response like this
After this again when you run the get API you can see all the sub documents are added to all documents.
Hope this helps.
This is my first time writing a MVC app in Node/Express/Mongoose so I could really use some help. My .find() command just doesn't find anything! :(
Structure is that I have a an /app folder in the root. /app folder contains /models (schemas), /controllers and /views in it. And I have app.js outside in the root.
Somewhere in app.js:
// all necessary config/setup stuff..
var mongoose = require('mongoose');
mongoose.connect(config.db);
var app = express();
require('./config/routes')(app)
In my routes.js file:
var skills = require('../app/controllers/skills');
app.get('/', skills.showall);
My controller skills.js contains:
var Skill = require('../models/skill');
exports.showall = function(req, res) {
Skill.find({}, function(err, docs){
if (!err) {
res.render('index', {title: 'Skilldom', skills: docs});
}
else {
throw err;
}
});
}
Finally my Model skill.js contains:
var mongoose = require('mongoose');
//Skill schema definition
var skillSchema = new mongoose.Schema({
name: String,
length: String,
});
var Skill = mongoose.model('Skill', skillSchema);
module.exports = Skill;
My index view renders, so I see the content from my index.jade template, but for some reason the find command in the model is not fetching anything. I can confirm that my database (in MongoHQ) has real data.
Any thoughts?
Change your Skill.js for this
var mongoose = require('mongoose');
mongoose.set('debug', true);
//Skill schema definition
var skillSchema = new mongoose.Schema({
name: String,
length: String,
});
var Skill = mongoose.model('Skill', skillSchema);
module.exports = Skill;
After that, you can see at the console if mongoose is doing your queries.
I was in the same situation as you describe and it turns out I didn't understand the magic of mongoose collection naming, in your code it will try to load the "skills" and if that's not what it's named in your mongo nothing will be returned. Should really toss a "so such collection" error instead imho.
This below method gives an alternate name for your collection
var skillSchema = new mongoose.Schema({
name: String,
length: String,
},{collection : 'Skill'});
or
var Skill = mongoose.model('Skill', skillSchema,''Skill);