Text search multiple fileds not working in nodejs and mongodb - node.js

I am trying to search by concatenating these firstName,middleName and lastName fields
Here is my model
var lectureSchema = new mongoose.Schema({
firstName:{
type:String,
require:"First Name can\'t be empty "
},
middleName:{
type:String,
require:"Middle Name can\'t be empty "
},
lastName:{
type:String,
require:"Last Name can\'t be empty ",
},
email:{
type:String,
require:"Email can\'t be empty "
}
};
lectureSchema.index({firstName:'text', middleName:'text',lastName:'text'});
mongoose.model('Lecture',lectureSchema);
And also here is my Function respond to search API
module.exports.findLecture=(req,res)=>{
var query = req.params.query;
Lecture.find({
$text: {
$search:query
}
}, function(err, result) {
if (err) throw err;
if (result) {
res.json(result)
} else {
res.send(JSON.stringify({
error : 'Error'
}))
}
})
}
here is the route
router.get('/findLecture/:query',checkerUser.findLecture);
But, this only seems to fetch documents that match the firstName field. It doesn't match middleName and lastName field.someone please help me.

I have implemented query to solve this,
Please follow the link,
https://mongoplayground.net/p/3GW2FYH95tj
You have to use aggregation queries to achieve your requirement.
db.collection.aggregate([
{
$project: {
name: {
$concat: [
"$firstName",
"$middleName",
"$lastName"
]
}
}
},
{
$match: {
name: {
$regex: "john1unknown1Doe1"
}
}
}
])
Replace "john1unknown1Doe1" with your regex value like new Regex(req.query.search).

Related

MongoError: The positional operator did not find the match needed from the query. at Function.create()

I am trying to update values into an object array(users) if it does not already exist in MongoDB. Here is my Schema:
ownerid:{
type: Number,
required: 'This field is required'
},
name:{
type: String
},
capacity:{
type: Number
},
basePrice:{
type: Number
},
users:[{
id: Number,
price: Number,
target: Number,
frequency: Number
}],
filePath:{
type: String
},
status:{
type: String
}
});
The following is my router method:
app.post('/userBid',urlEncodedParser,function(req,res){
resName=req.body.resName;
console.log(resName);
Resource.find({"name":resName},{"users.id": userid},function(err,existingUser){
if (!existingUser){
console.log("already in queue");
//res.render('userHome.ejs');
}
else{
console.log("in update");
Resource.update({'name': resName},
{'$set': {
'users.$.frequency': 1,
'users.$.id': userid,
'users.$.price': req.body.price,
'users.$.target': req.body.target
}},{'multi': true},
function(err,model) {
if(err){
console.log(err);
return res.send(err);
}
return res.json(model);
});
}
});
});
I have tried using $push but that does not seem to work either. Also I can't use '0' instead of '$' as multiple users will be inserted by the users and I need to store them all.
Issue :
Reason why we use $ is to update a specific object/few specific objects in an array field that meet our condition. So when you use any positional operators like $ or $[] then in filter part of .update({filterPart},{updatePart}) query you need to use a filter to find specific object in array. So for example if id field is unique in users array then you can use it to filter/find the object needs to be updated.
Try this below code :
app.post("/userBid", urlEncodedParser, function (req, res) {
resName = req.body.resName;
console.log(resName);
/** Use findOne if `name` is unique.
* Cause `existingUser` will be array, instead findOne will return an object or null - So you can just do if(existingUser)to check true values */
Resource.find({ name: resName }, { "users.id": userid }, function (
err,
existingUser
) {
if (!existingUser) {
console.log("already in queue");
//res.render('userHome.ejs');
} else {
console.log("in update");
Resource.update(
{ name: resName, "users.id": userid }, /** `"users.id": userid` is the only change needed */
{
$set: {
"users.$.frequency": 1,
"users.$.id": userid,
"users.$.price": req.body.price,
"users.$.target": req.body.target,
},
},
{ multi: true },
function (err, model) {
if (err) {
console.log(err);
return res.send(err);
}
return res.json(model);
}
);
}
});
});

Mongoose reports no error on updating, but does not update

losing my mind here for something for a MongoDB document update with Mongoose, not reporting any error but not actually updating successfully.
I have this schema:
/**
* Branch Schema
*/
let BranchSchema = new Schema({
name: String,
domain: String,
email: String,
bm: { type: Schema.ObjectId, ref: 'User' },
st: [{ type: Schema.ObjectId, ref: 'User' }],
stockCurrent: {
paper: Schema.Types.Object,
ink: Schema.Types.Object
},
stockNeeded: {
paper: Schema.Types.Object,
ink: Schema.Types.Object
},
}, { versionKey: false, usePushEach: true });
mongoose.model('Branch', BranchSchema);
Trying to update stockCurrent, using this logic:
Branch.findById(config.branch.id, function (err, branch) {
if (err) {
res.status(422).send({
message: 'הסניף לא נמצא'
});
} else {
console.log(branch);
Object.keys(req.body.stock).forEach(function (type) {
Object.keys(req.body.stock[type]).forEach(function (code) {
if (req.body.stock[type][code] > 0) {
if (typeof branch.stockCurrent[type][code] === 'undefined') {
branch.stockCurrent[type][code] = 0;
}
branch.stockCurrent[type][code] += req.body.stock[type][code];
}
});
});
console.log(branch);
branch.save(function (err, updated) {
console.log("err: " + err);
if (err) {
stock.remove();
res.status(422).send({
message: 'שגיאה בשמירת מלאי'
});
} else {
console.log(updated);
res.send({
message: 'מלאי נוסף בהצלחה'
});
}
});
}
});
I get to to success part, having my console log this:
{
"_id":5dd276a6bcc29a13789fcecb,
"name":"בצלאל ארכיטקטורה",
"domain":"bezalel.eazix.io",
"email":"eazix.1.bezalel#gmail.com",
"bm":5cdd2130d192ea03a87d2dfd,
"stockNeeded":{
"ink":{
"GY":2,
"PM":2,
"M":2,
"MBK":2,
"PBK":2,
"PC":2,
"Y":2,
"C":2,
"waste":2
},
"paper":{
"COATED":5,
"PLAIN":5,
"PHOTO":3
}
},
"stockCurrent":{
"paper":{
"PLAIN":0
},
"ink":{
"waste":0
}
},
"st":[
]
}{
"_id":5dd276a6bcc29a13789fcecb,
"name":"בצלאל ארכיטקטורה",
"domain":"bezalel.eazix.io",
"email":"eazix.1.bezalel#gmail.com",
"bm":5cdd2130d192ea03a87d2dfd,
"stockNeeded":{
"ink":{
"GY":2,
"PM":2,
"M":2,
"MBK":2,
"PBK":2,
"PC":2,
"Y":2,
"C":2,
"waste":2
},
"paper":{
"COATED":5,
"PLAIN":5,
"PHOTO":3
}
},
"stockCurrent":{
"paper":{
"COATED":1,
"PHOTO":2,
"PLAIN":0
},
"ink":{
"PM":1,
"waste":0
}
},
"st":[
]
}**"err":null**{
"_id":5dd276a6bcc29a13789fcecb,
"name":"בצלאל ארכיטקטורה",
"domain":"bezalel.eazix.io",
"email":"eazix.1.bezalel#gmail.com",
"bm":5cdd2130d192ea03a87d2dfd,
"stockNeeded":{
"ink":{
"GY":2,
"PM":2,
"M":2,
"MBK":2,
"PBK":2,
"PC":2,
"Y":2,
"C":2,
"waste":2
},
"paper":{
"COATED":5,
"PLAIN":5,
"PHOTO":3
}
},
"stockCurrent":{
"paper":{
"COATED":1,
"PHOTO":2,
"PLAIN":0
},
"ink":{
"PM":1,
"waste":0
}
},
"st":[
]
}
I can see the here the initial state, the updated version before saving, and the the err:null, and the allegedly updated document.
but alas! the document wasn't really updated. it remains the same.
I have tried many things, searching and looking for similar cases, checking my schema, adding useStrict:false to the schema, nothing helps.
Mongoose ver 4.13.20, Mongodb ver 3.6.17
SOS
Dor
I'm guessing the SchemaTypes are the problem? In Mongoose 4.x, these are the only valid SchemaTypes:
String
Number
Date
Buffer
Boolean
Mixed
Objectid
Array
Notice that Mixed is an option but not Object. You need to tell Mongoose that you updated a Mixed field using model.markModified('pathName'). See the Mixed docs.
So in your case, the code below may fix the issue:
branch.markModified('stockCurrent');
branch.save(function (err, updated) {
// ...

Can't get figure it out: mongoose update a doc inside an array inside a doc

Well I want to update a doc inside an array by the index. My schema and code look like this
var userSchema = mongoose.Schema({
email: {
type: String,
required: false,
minlength: 4,
trim: true
},
bla: []
});
// this is the example object that I get from the db
{
"id" = "somethingUniq",
"email" = "this#email.workdamnit",
"bla" = [{"blabla": "something"},{"blabla":"somethingelse"}]
}
User.findOneAndUpdate({ "_id": "somethingUniq", "bla.1.blabla": "something" },
{
"$set": { "bla.$.blabla": "something new" },
function(err, doc) {
if (err) console.log('err in update', err);
console.log('doc', doc)
}
})
So that blabla with index of 1 gets updated. I have tried for hours now, and can't get anything I try to work...
The end result should look like :
{
"_id" = "somethingUniq",
"email" = "this#email.workdamnit",
"bla" = [{"blabla": "something"},{"blabla":"something new"}]
}
The $push operator appends a specified value to an array.
( https://docs.mongodb.com/manual/reference/operator/update/push/ )
Try $set in your case :
User.findOneAndUpdate(
{ "_id": "somethingUniq",
"bla.1.blabla": "something"
},
{ $set:{
"bla.$.blabla": "something new"
}
},
function(err,result){
if (!err) {
console.log(result);
}
});
And make sure you're using the correct one between _id and id because you're showing both of them in your subject.
In the case you're looking for id, change also :
"_id": "somethingUniq"
To :
"id": "somethingUniq"

Updating multiple sub-documents with Mongoose and Node

I have a Model wich contains an array of sub-documents. This is a Company:
{
"_id" : ObjectId(":58be7c236dcb5f2feff91ac0"),
"name" : "sky srl",
"contacts" : [
{
"_id" : ObjectId("58be7c236dcb5f2feff91ac2"),
"name": { type: String, required: true },
"company" : ObjectId("58be7c236dcb5f2feff91ac0"),
"email" : "sky#gmail.com",
"chatId" : "",
"phone" : "123456789",
"name" : "John Smith"
},
{
"_id" : ObjectId("58be7f3a6dcb5f2feff91ad3"),
"company" : ObjectId("58be7f3a6dcb5f2feff91ad1"),
"email" : "beta#gmail.com",
"chatId" : "",
"phone" : "987654321",
"name" : "Bill Gaset"
}
],
"__v" : 1
}
I have several companies, and I want to update the field chatId of all the contacts in all the companies, that matches the phone I am searching for.
My Schema definitions (simplified, for focusing on question):
var contactSchema = new Schema({
[...]
phone: { type: String, required: true },
email: { type: String },
chatId: { type: String },
company: Schema.Types.ObjectId,
});
var companySchema = new Schema({
name: { type: String, required: true },
type: { type: String, default: "company" },
contacts: [contactSchema]
});
I tried
var conditions = { "contacts.phone": req.body.phone };
var partialUpdate = req.body; //it contains 'req.body.phone' and 'req.body.chatId' attributes
Company.find(conditions).then(
function (results) {
results.map( function(companyFound) {
companyFound.contacts.forEach(function (contactContainer){
if (contactContainer.phone == partialUpdate.phone) {
contactContainer.chatId = partialUpdate.chatId;
Company.save();
companyFound.save();
contactContainer.save();
results.save();
}
//not sure of what to save, so i save everything
companyFound.save();
contactContainer.save();
results.save();
});
});
});
following this answer; but it doesn't works. It does not save anything, what I'm doing wrong?
I have never done this before, but worth a try.
Maybe you need to use $elemMatch.
// find the companies that have contacts having the phone number
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone }}).exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
// see if you can at least get the query to work
console.log(companies);
async.eachSeries(companies, function updateCompany(company, done) {
// find and update the contacts having the phone number
company.contacts.forEach(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].chatId = req.body.chatId;
}
});
company.save(done);
}, function allDone (err) {
console.log(err);
});
});
Note, I am using async.js to do async operations on multiple items.
Honestly, I would have simply made contacts an array of Contact references -- much easier to query and update.
Just for the records: I did this to make it work without async.js:
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone } })
.exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
console.log("companies: " + JSON.stringify(companies, null, 4));
companies.forEach(function (company) {
company.contacts.map(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].telegramChatId = req.body.telegramChatId;
}
});
company.save();
},
function allDone(err) {
console.log(err);
});
});`

How do i $set and $push in one update MongoDB?

I'm trying to $push and $set at the same time, $push is working just fine, when it comes to $set, it generates this error:
MongoError: The positional operator did not find the match needed from
the query. Unexpanded update: files.$.name
Here's the code
Course.update(
{
_id: req.body.courseId,
'files.fileUrl': { $ne: url }
},{
$push: { files: { fileUrl: url } },
$set: {'files.$.name': file.name},
}, function(err, count) {
if (err) return next(err);
console.log("Successfully saved")
});
and the ORM model, I'm using mongoose
var CourseSchema = new Schema({
files: [{
fileUrl: String,
name: { type: String, default: 'File name'}
}]
});
Any help would be appreciated. Thanks.
As the error states looks like the query used is returning no documents or returning documents having no files[].
Another reason for which it might be throwing error is that you're trying to $push & $set in the same field files and probably running into an issue similar to https://jira.mongodb.org/browse/SERVER-1050
IMHO, there is no good reason to use the same field in $push & $set, instead you can simply change
$push: { files: { fileUrl: url } },
$set: {'files.$.name': file.name},
to
$push: { files: { fileUrl: url, name: file.name } },
I have written similar kind of query for my project
Hope u could relative this to your scenario
exports.candidateRating = function(req, res) {
console.log(req.query);
console.log(req.body.RoundWiseRatings);
Profiles.update({
"name": req.query.name
}, {
$set: {
"ratings": req.body.ratings,
},
$push: {
"RoundWiseRatings": req.body.RoundWiseRatings
}
}, {
multi: true
}, function(error, profiles) {
if (error) {
}
return Profiles.find({
name: req.query.name
}, function(err, profiless) {
console.log(profiless);
if (err) {
return handleError(res, err);
}
return res.status(200).json(fnStruncturedData(profiless[0].RoundWiseRatings));
});
});};
And this worked for me :)

Resources