Not able to create index using mongoose - node.js

I am building a search feature in a Node.js application which uses Mongoose, creating a full-text search index in Mongo:
postSchema = mongoose.Schema({
xx : String
.......
}).index({
'xx':'text'
});
Post = mongoose.model('Post',postSchema);
And execute the search as follows:
find = {'$text':{'$search':query}};
findScore = {'score':{'$meta':'textScore'}};
sort = {'score': {'$meta':'textScore'} };
Post.find(find, findScore).sort(sort).exec(function (err, data) {
if (err){
logging.log(err);
} else {
logging.log(data);
}
});
When I run the program, I get the following error:
'Unable to execute query: error processing query \n planner returned error: need exactly one text index for $text query'
Any help would be appreciated.

A collection can have at most one text index. You need to check it any of the text index is previously created.

Related

Sequelizer : JSONB postgres query not working

I am trying to get the records on the basis of some key that are in jsonb, i am using sequelizer as ORM and postgres as a DB . I am getting empty array of leads unexpected ...
whereArr.push(db.where(
db.cast("dataJson.basicInfo.firstName.value", 'text'),
{ [Op.iLike] : "%k%" }
));
searchBy = {
where: {
...whereArr
}
};
let leads = await Lead.findAndCountAll({
...searchBy,
...orderBy,
...paginate
});
The code work fine if i am using the column name other than jsonb's column .
I am unable to figure out the issue. please guide how can i achieve that .
Thank You

How to search data in mongodb with dynamic fields using mongoose?

I've a node.js api in which user sends the required fields as an array to be fetched from the mongodb database. I need to find the data of that fields using Find query. I've written forEach statement to loop through that array and got the array elements. But when I try to get the results by inserting the array elements in the query, it doesn't giving the required results. Could any one please help me in resolving the issue by seeing the code below?
templateLevelGraphData: async function(tid,payload){
let err, templateData, respData = [], test, currentValue;
[err,templateData] = await to(Template.findById(tid));
var templateId = templateData.templateId;
payload.variables.forEach(async data=>{
console.log(data); //data has the array elements like variables=["humidity"]
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({},{data:1}).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue);
});
return "success";
}
The expected output is,
[ { humidity: 36 } ]
But I'm getting only _id like,
[ { _id: 5dce3a2df89ab63ee4d95495 } ]
I think data is not applying in the query. But I'm printing the data in the console where it's giving the correct results by displaying the array elements like, humidity. What I need to do to make it work?
When you are passing {data: 1} you are passing an array where is expecting name of column.
You have to create an object where the keys are going to be the elements of the array and set them to 1.
const projection = data.reduce((a,b) => (a[b]=1, a), {});
[...] .find({}, projection) [...]
Actually I got the solution.
for(let i=0;i<payload.variables.length;i++){
var test = '{"'+ payload.variables[i] +'":1,"_id":0}';
var query = JSON.parse(test);
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({"deviceId":deviceId},query).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue); //It's giving the solution
}

Mongoose - Modle.update() updates wrong document - Cast Error

I need some help to clear some things up.
I have a Model:
var Event = new Schema({
event_code: String
, segments: [Segment]
});
The creation of new documents work very well like perfect. When it comes to update certain documents I ran into some troubles.
When I do this (code below): = it only updates the first document, even if the id does not match
function edit_event (id, new_name, callback) {
Event.update(id, {$set:{event_code: new_name}}, function(err, doc) {
if (err) throw err;
callback();
});
}
When I do this (code below): = it gives me an Error (see below)
function edit_event (id, new_name, callback) {
Event.findByIdAndUpdate(id, {$set:{event_code: new_name}}, function(err, doc) {
if (err) throw err;
callback();
});
}
Error when using findByIdAndUpdate: Cast to ObjectId failed for value ""58fdbde31bff83141b376508"" at path "_id" for model "Event"
Please, i'm desperate :! :/
UPDATE
I figured out that the id that i'm trying to pass get stored with "" around it, so when i am looking for document with matching ID it puts an extra pair of "" around it so it ends up like ""id""
UPDATE 2
When I am listing all my documents, it returns:
{ _id: 58fdbde31bff83141b376508,
event_code: 'TestABC',
__v: 0,
segments: [] }
Then when i store the id in an HTML form it adds extra pair of "" around it ... that's not the case with event_code. Why is that ?
Looks like you performed unneeded JSON.stringify and that's why you get quotes around the id. Calling JSON.parse should solve the issue:
Event.findByIdAndUpdate(JSON.parse(id), {$set:{event_code: new_name}}, ...

Search query string from array list of string of different objects in mongodb

I want to search a query string against the array of string stored in array of all the objects presents
my database structure looks like this
[0:
destination: ......
name: ......
name_list: [""some place", "some place 2", "some place3"]
1:
destination: ......
name: ......
name_list: [""some place4", "some place 5", "some place3"]
2:
destination: ......
name: ......
name_list: [""some place56", "some place 34", "some place3"]
and so on ....
]
let's say
I want to get all the objects whose name_list array contains string "someplace3" but the query i will receive might only be "place3", since user might not know the complete or exact name. I can't figure how to search, I'am using expressjs module to search in my mongodb database like:
route.find({name_list: "place3"}, function(err, routes) {
if (err) throw err;
routeTosend = routes;
});
but obviously I am not getting any results, but if i search exactly like someplace3 it returns all the objects.
I am completely new to database hence mongodb as well, if anyone can help would really appreciate.
You have to make use of $regex provided by mongodb. You can do something like this
route.find({"name_list": {$regex : /.*places3.*/}}, function(err, routes) {
if (err) throw err;
routeTosend = routes;
});
To use variable inside regex you have to create regex object from a string using RegExp constructor
var query= "place";
regx = new RegExp('.*' + query + '.*','i');
route.find({"name_list": regx}, function(err, routes) {
if (err) throw err;
routeTosend = routes;
});

Express js Mongoose alternative to MySQL % Wildcard

I've been reading up and tried a few different code snippets that others have had success with, but I can't seem to get it to work.
What I'd like is for users to search using only part of the term i.e pe for 'peter'. I'd like to have a wildcard on the search term.
My code so far, which isn't working:
router.get('/:callsign', function(req,res){
var search = req.params.callsign;
var term = escape(search);
term = term.toUpperCase();
if(search=="*" || search==""){
res.redirect("/");
}
User.find({'callsign' : new RegExp('^'+term+'$', "i") }, function(err, callsign){
if(err)
{
console.log('No user found'+err);
req.flash('message','Sorry, something went wrong. Try again.');
res.render('callSearchResults'),{
message: req.flash('message'),
title: 'Sorry, no results'
}
}
if(callsign){
console.log('Callsign:'+callsign+term);
res.render('callSearchResults',{
call: callsign,
title: 'You searched for '+search,
query: term
});
}else{
console.log('No entries found'+search);
}
});
});
Also, 'callsign' callback is constantly true - even when there are no results!
You are using an RegExp for this search. Literal ^ mean that pattern must be at the beggining of string, and $ that at the end. If you want just to match part you don't need to add them, so example below:
new RegExp(term, "i")
Also there is a good mechanism of full-text search build-in mongo. You can read about them from official docs.
About queries in mongoose, when there is now object and checking in callback. The returned object is Array of documents, and in JS empty array is casted to true statement. Instead check lenght array, like this:
if(callsign.length > 0) {
// Logic
} else {
// Nothing found
}

Resources