How do i $set and $push in one update MongoDB? - node.js

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 :)

Related

Text search multiple fileds not working in nodejs and mongodb

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).

mongodb using $not getting undefined, in NodeJs

I am trying to make a find command in Mongo using $not as i see in this link,
await Match.find(
{
type:"Friendly", status:"Pending", "date.fullDate":{$gt: date},
$not:{$or: [{"team1.players":{$elemMatch: {_id:playerId}}}, {"team2.players":{$elemMatch: {_id:playerId}}}]}
}).sort({'date.fullDate':1}).exec(function(err, doc) {
console.log(doc)
return res.send({data: doc});
});
However, i am getting undefined.
I am thinking the problem is with the $not because when i remove it and make the command like this it works.
await Match.find(
{
type:"Friendly", status:"Pending", "date.fullDate":{$gt: date},
$or: [{"team1.players":{$elemMatch: {_id:playerId}}}, {"team2.players":{$elemMatch: {_id:playerId}}}]
}).sort({'date.fullDate':1}).exec(function(err, doc) {
console.log(doc)
return res.send({data: doc});
});
Note: that team2 could be null in the documents.
Any ideas why i am getting this undefined.
My document look like this:
match:{
team1:{
players:[
_id:value,
otherfields...
]
},
team2:{
players:[
_id:value,
otherfields...
]
}
}
await Match.find({
type: "Friendly", status: "Pending", "date.fullDate": { $gt: date },
$or: [
{
$not: {
"team1.players": { $elemMatch: { _id: playerId } }
}
},
{
$not: {
"team2.players": { $elemMatch: { _id: playerId } }
}
}
]
}).sort({ 'date.fullDate': 1 }).exec(function (err, doc) {
console.log(doc)
return res.send({ data: doc });
});
I had to use $nor instead of $not:{$or:[]}
Similar question here.

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) {
// ...

Mongoose update returns undefined

How can I update a field with new properties that is initially set to be an empty object?
For example, I have the following schema:
import mongoose from 'mongoose';
var RunSchema = mongoose.Schema(
{
runId: { type: String },
reports: {
cookieSummary: {
name: String,
path: String
}
}
}
)
export default mongoose.model('Run', RunSchema);
And I'm trying to update the following document:
{
"_id": {
"$oid": "5a0565c2537e0b5d9d08ee6b"
},
"__v": 0,
"reports": {},
"runId": "8r4LNN3fRqd3qNgdW"
}
But when I run this code, it returns undefined:
Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'},
{
$set: {'reports.cookieSummary': { 'name': 'test' }},
}, (err, doc) => { console.log(doc) })
The object notation works after adding type to fields, like this: name: { type: String }
Try to use dot notation, as you're setting just one field:
Run.findOneAndUpdate(
{ runId: '8r4LNN3fRqd3qNgdW' },
{ $set: {'reports.cookieSummary.name': 'test' } },
(err, doc) => { console.log(doc) })
According to the docs, the command you're using should work but you write it wrongly. Try like this:
Run.findOneAndUpdate(
{ runId: '8r4LNN3fRqd3qNgdW' },
{ $set: { 'reports.cookieSummary': {'name': 'test'} } },
(err, doc) => { console.log(doc) })
if it does not work, maybe mongo expect that the object matches its schema when you use the command like this. But I don't think so.
Let me know.
Your query for update a document is good only the mistake is at the end of curly braces of $set. You entered un-necessary comma at the end that is actually creating problem in this case. So I suggest you to remove it and run this :
Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'},
{
$set: {'reports.cookieSummary': { 'name': 'test' }}
}, (err, doc) => { console.log(doc) });
and then see. Rest of your query is fine.
Hope It will work for you.
Thanks.
Try using below code, it will update the document and return the updated document.
var Q = require('q');
var deferred = Q.defer();
Run.findOneAndUpdate({ runId: '8r4LNN3fRqd3qNgdW' }, { $set: { 'reports.cookieSummary.name': 'test' } }, { new: true },
(err, doc) => {
console.log(doc);
deferred.resolve(doc);
});
return deferred.promise;
I made a small change. Test this solution.
Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'},
{
$set: {"reports": {'cookieSummary':{'name': 'test'}}},
}, (err, doc) => { console.log(doc) })

How to send a updated values in nodejs?

I need to send all urls including last updated values from mongodb.
but i only get previous updated values.Can any body tell the me solution .
new_add_schema.findOneAndUpdate(
{
user_id: req.body.user_id
},
{
$push:
{
filename:
{
url:img_filename
}
}
},
function(err, doc) {
console.log(doc)
});
In mongoose you can pass options as the third argument for this method. If you pass new: true in options then Mongo will return the updated document. It is false by default.
So query like this -
new_add_schema.findOneAndUpdate(
{
user_id: req.body.user_id
},
{
$push:
{
filename:
{
url:img_filename
}
}
},
{new: true}, // notice this options argument
function(err, doc) {
console.log(doc)
});
You can see the documentation here.

Resources