why this mongoose text search doesn't work - javascript

Even though I have similar data in collection, result always comes back empty. I have ingredients in array[object]. That means qty:1 unit:spoon ing:salt and I want only ing to be searchable. I have mongoose debug enabled and it shows:
Mongoose: recipes.ensureIndex({ 'Ingridients.ing': 'text' }) { background: true, safe: undefined }
This is the code:
var RecipesSchema = new mongoose.Schema({
Name: {type: String, required: true},
Desc: String,
Ingridients: [{qty:Number, unit:String, ing:{ type: String, index: "text" } }],
created: { type: Date }
});
Recipe.find({ $text : { $search : "salt egg potato peper" } },
{ score : { $meta: "textScore" }
})
.sort({ score : { $meta : 'textScore' } })
.exec(function(err, recipe) {
// callback
if(err) console.log(err);
res.render('list', { recipes: recipe });
});

after i tried on localhost and it worked, switched on mongolab.com by dropping and recreating collection and indexes again. it was not able to index correctly
ERR: planner returned error: need exactly one text index for $text query', code: 17007

Related

Trying to figure out how to get my MongoDB Database to bring up items that belong to a certain user (by ID)

I'm trying to get my Mongo Database to extract out the items (Portfolio pics) that a user has submitted, but when I previewed the items extracted via the Console logs,it displayed all of the portfolio pieces for everyone instead of just that specific user.
Here are the codes that I typed in Javascript to attempt to get it to work so far:
On the back end side:
(For the routes)--------------------------------------
//GET - get all portfolio pieces for a certain user ----------------------
router.get('/:id', Utils.authenticateToken, (req, res) => {
Portfolio.findById({user: req.body._id}).populate('user', '_id firstName lastName displayName')
console.log({user: req.body._id})
.then(userPortfolio => {
if(userPortfolio == null){
return res.status(404).json({
message: "No portfolio pieces found"
})
}
res.json(userPortfolio)
})
.catch(err => {
console.log(err)
res.status(500).json({
message: "Problem getting portfolio pieces"
})
})
})
For the Portfolio Model (Schema) file:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const Utils = require('./../utils')
// schema
const portfolioSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
description: {
type: String,
required: true
},
user: {
type: Schema.Types.ObjectId,
required: true,
ref: 'User'
},
image: {
type: String,
required: true
},
tag: {
type: String,
required: true
},
link: {
type: String,
}
}, { timestamps: true, collection: 'portfolioPs' })
// model
const portfolioModel = mongoose.model('Portfolio', portfolioSchema)
// export
module.exports = portfolioModel
And for the front end side:
init(){
console.log('ProfileView.init')
document.title = 'Profile'
this.userPortfolio = null
this.render()
Utils.pageIntroAnim()
this.getUserPortfolio()
}
async getUserPortfolio(){
try{
this.userPortfolio = await PortfolioAPI.getUserPortfolio(Auth.currentUser._id)
console.log(this.userPortfolio)
this.render()
}catch(err){
Toast.show(err, 'error')
}
}
Do let me know if you need any further code to help me resolve this issue mates! Thanks in advance!
use Portfolio.find({user: req.body._id}) to get list of of all items that a user has submitted. It will return an array result
P.S:
Portfolio.findById(someId) is used to fetch only 1 specific document where result is an object by matching its _id field

Error Handling: E11000 duplicate key error collection

I am having a problem with the user model that I'm using with Mongoose and MongoDB to create each profile in my database. It works fine to post one user, but throws the following error if I logout and try again:
{
"name": "MongoError",
"message": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }",
"driver": true,
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }"
}
According to mongoose documentation: If there is more than one document (a second user) without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error. I don't know how to set this _id property for the trackers property –– I thought it generated automatically!
Here's the trackers part of my Schema. And the relevant case_id property, which seems to be throwing the "null" error.
The whole repository can be found on my Github here, but the likely problem spots are the ones I highlighted, I think. Here's the github link: https://github.com/KingOfCramers/node_login_with_trackers
user model:
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
trim: true,
minLength: 1,
unique: true,
validate: {
validator: (value) => {
return validator.isEmail(value);
},
message: '{VALUE} is not a valid email'
}
},
password: {
type: String,
required: true,
minlength: 6
},
tokens: [{
access: {
type: String,
required: true
},
token: {
type: String,
required: true
}
}],
trackers: {
tweets: [TwitterSchema],
legislation: [LegislationSchema],
court_cases: [CourtCaseSchema]
},
frequency: [EmailSchema]
});
Express route:
app.post("/users", (req,res) => {
var body = _.pick(req.body, ['email', 'password']);
body.frequency = {
alert_time: new Date(),
email: req.body.email
}
var user = new User(body);
user.save().then(() => {
return user.generateAuthToken();
}).then((token) => {
res.header("x-auth", token);
res.send(user);
}).catch((e) => {
res.status(400).send(e);
});
});
Test (mocha):
it("Should post a new user", (done) => {
var email = "uniqueemail#example.com"
var password = "9webipasd"
supertest(app)
.post("/users") // Post request to the /todos URL
.send({
email,
password
})
.expect(200)
.expect((res) => {
expect(res.headers).toIncludeKey('x-auth')
expect(res.body._id).toExist();
expect(res.body.email).toBe(email);
})
.end((err) => {
if(err){
return done(err);
}
User.findOne({email}).then((user) => {
expect(user).toExist();
expect(user.password).toNotBe(password);
done();
}).catch((e) => done(e));
});
});
My guess is that there is an index on CourtCaseSchema.case_id which does not allow duplicates.
I think you could check (in a mongo shell) that with CourtAPIDev.court_cases.getIndexes() (I think your db is named CourtAPIDev and the collection is named court_cases but I am not sure about that).
Also if you clean the test db after each run, that would explain why the tests are passing, since there is no more than one user.
Turns out, it was to do with my mongodb database, not any of my code. After searching around online, I found that if I logged into the mongo shell and then dropped all indexes from the users collection, it solved my problem. Could someone explain why this was causing my program to crash? I think it may have to do with an old user model, but I don't really understand. Thanks!
Even if you have all of your keys as unique=False, you may still get E11000 duplicate key error. So in that case, just follow these steps and check if your error is resolved.
Delete all documents from the collection (e.g. db.collection_name.deleteMany({}))
Drop the COLLECTION (NOT THE DATABASE) (e.g db.collection_name.drop())
Cheers !!

Node.JS & Mongoose - insert item into an array in the database

I am currently working on a project and I am stuck with inserting an item into an array/object in the database. What I am trying to do is to add the id of a 'upvoted' post to an array/list in the 'User' Collection, however, I cannot seem to get it to work.
The code for my schemas is as follows:
// this is a child scheme/sub-document
var uvpSchema = new Schema();
uvpSchema.add({
post: String
});
var dvpSchema = new Schema();
dvpSchema.add({
post: String
});
//main schema
var userSchema = new Schema({
firstname: { type: String, required: true },
lastname: { type: String, required: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
upVotedPosts: [uvpSchema],
downVotedPosts: [dvpSchema],
created_at: Date,
});
And here is the code in my 'routes.js' to insert the id of the post into the array:
var newPush = {
post: postID // postID is a variable that I have already defined
};
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
The error I receive in my terminal is:
{ _id: 595f68b5fadd49105813f8a4 },{ _id: 595f693d3c2c21189004b0a7 },{ _id: 595f70a2df80e0252894551b }
events.js:163
throw er; // Unhandled 'error' event
^
Thanks in advance ;-)
Route.js
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
You dont need to explicitly push, since you pushed using findOneandUpdate - $push
Refer here
Secondly , its
user.save()
and not
User.save
First of all, I'd like to thank everyone's' help ;-)
I finally managed to get it partially working! My problem was that my functions were running asynchronously, causing some problems. I solved this by adding callback functions to each mongoose function.
However, the same error is still being returned, causing the server to crash. Everything else works; the new item is added to the array.
Is there anyway to ignore the error so that the server doesn't crash?

Sequelize with postgresql saving array

I am using sequelize in my application. I have postgres as underlying database.
But when I tried to save instances I got following error
[error: missing dimension value]
I have the following model
module.exports = function(sequelize, DataTypes) {
var Mymodel = sequelize.define('Mymodel', {
id: {type : DataTypes.INTEGER, autoIncrement : true, primaryKey: true},
title: {
type: DataTypes.STRING(128),
validate: {
notNull: true,
notEmpty: true
}
},
tags: DataTypes.ARRAY(DataTypes.TEXT)
});
return Mymodel;
}
I am sending http post request as
{
"title":"Test challenge",
"tags" : "['JAVA','REST','API']"
}
I am saving object like this
Mymodel.create(model).success(function(model) {
callback(null, challenge);
}).error(function(err) {
callback(err, null);
});
I tried sending over your model object as you stated and did get the error SequelizeValidationError: "['JAVA','REST','API']" is not a valid array. Perhaps you got a different error on an older version of Sequelize. Then, I made sure the tags value was a JavaScript array instead of a string and it worked.
Mymodel.create({
title: 'Test challenge',
tags: ['JAVA','REST','API']
}).then(function() {});

How do I update an embedded document with a nested hierarchy?

I have an embedded document that needs to be updated. I have managed to get everything working except for one scenario: I am unable to get an embedded document with a nested hierarchy to get updated. Here is an example of what I'm attempting to do:
console.log('Phone type: ' + req.body.phone.type); // prints, e.g., 'Phone type: Work'
console.log('Phone #: ' + req.body.phone.number); // prints, e.g., 'Phone #: 555-555-5555'
var updateData = {
"user.$.contact_info": {
email: req.body.email,
phone: {
type: req.body.phone.type,
number: req.body.phone.number
}
}
};
Group.update(
{ "user._id" : req.params.user_id },
{ $push : updateData },
function(err,data) {
console.log('Success!'); // I see the "Success!" message every time I save a record
}
);
Schema:
var contactInfoSchema = mongoose.Schema({
created : {
type: Date,
default: Date.now
},
email : String
phone: {
type: String,
number: String
}
});
var userSchema = mongoose.Schema({
created : {
type: Date,
default: Date.now
},
contact_info : [contactInfoSchema]
});
var GroupSchema = mongoose.Schema({
created : {
type: Date,
default: Date.now
},
users : [userSchema]
});
What I find is that I can create records, but only the email address is stored, not the phone information. When inspecting the console I can see that the phone type and phone number info is being sent, but it just isn't updating in the database. What am I doing wrong?
The problem in in the "contactInfoSchema" with the use of the "type" keyword. You need this:
var contactInfoSchema = mongoose.Schema({
created : {
type: Date,
default: Date.now
},
email : String
phone: {
"type": { "type": String },
number: String
}
});
So basically mongoose is confused since you tried to call a "sub-document" field "type", and it thinks that is the data "type" for the field "phone". Declared as above all works fine.

Categories