This is my schema.
team_year: String,
team: [{
_leader: String,
_member:[{
_name: String,
_phone: String,
_age: Number,
_gender: String,
_comment:[{
_date: String,
_contents: String,
_attendance: Boolean
}]
}]
}]
I have data
{ team_year: 2015
team: [
{
_leader: tom
_member: [
{_name: mike,
_phone: 2222
]
},
{
_leader:jack,
_member: []
}
]
}
I want to register a team member of Jack.
team_schema.findOneAndUpdate(
{team_year: '2015', 'team._leader' : 'jack'},
{$push: {
'team._member': req.body
}
},
function(err, post){
if (err) next(err);
res.end("success");
});
but it doesn't work.
Please help me.
I use
Node.js + express + MongoDB
I'm not good at English. T^T
You need to specify the index of the object for which you want to insert an object (nested array). For this you can use the positional operator ('$') provided by MongoDB. See here for more info.
So this query should work:
team_schema.findOneAndUpdate(
{team_year: '2015', 'team._leader' : 'jack'},
{$push: {
'team.$._member': req.body //The $ symbol resolves to an index from the query
}
},
function(err, post){
if (err) next(err);
res.end("success");
});
Related
Search retrieves result only in parent level. search with $or condition returns empty array for subdocument level filter/search. $or doesn't work for subdocument level search. Any fixes for this or any mistakes in my code?
exports.getAllProduct = (req, res, next) => {
categories.find({$or:[{“categoryName”:{ $regex: req.params.id, $options: ‘i’ }},
{“subcategory.$.productName”:{ $regex: req.params.id, $options: ‘i’ }}]},
(err, products) => {
console.log(“Products:“+JSON.stringify(products));
if (err) {
return res.status(400).json({
error: “No Products found”+err
});
}
res.status(200).json(products)
});
};
const categorySchema = new mongoose.Schema({
categoryName: {
type: String,
trim: true
},
subcategory: [ {
subcategoryName: {
type: String,
trim:true
},
productCode: {
type: String,
trim: true
}]});
http://localhost:3000/category/getAllProduct/fruits
What mistake why $or is not working? I'm using mongoDB 4.4.1 and mongoose 5.10.8 and Mac OS Catalina.
As I can see sub-category is an array..you should check in the second parameter of the $or if the input is “$in” array.
Check this post
MongoDB query IN array of object
If I'm reading your mongo query correctly, you have a $ in subcategory.$.subcategoryName which is most likely causing the issue you are seeing. Use subcategory.subcategoryName to query against that value.
See below:
categories.find({
$or:[
{
“categoryName”:{
$regex: req.params.id,
$options: 'i'
}
},
{
“subcategory.subcategoryName”: {
$regex: req.params.id,
$options: 'i'
}
}
]},
(err, products) => {}
);
Also, always try to format your code cleanly as in this example. It makes finding solutions easier.
If you do not need the query to be case insensitive the below query will be cleaner:
categories.find({
$or:[
{
“categoryName”: req.params.id
},
{
“subcategory.subcategoryName”: req.params.id
}
]},
(err, products) => {}
);
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);
}
);
}
});
});
1.I Don't get the Item in Electro Array but the whole doc
getItem(data){
dbswap.findOne(
{ 'swap.Items.Electro.id':data.id,
'swap.Items.Electro.id':data.id }, function(err,item){
if(err){
return (err);
}
if(item){
console.log(item);
}
});
} // EOF
This is my Schema
1.I am trying to get the item i create in Electro only, I don't want the whole object i am getting at the moment.
var swapSchema = new mongoose.Schema({
swap: {
name: String,
Items: {
Electro: [
{
name: String,
info: String,
price: Number,
dateCreated: Date,
category: String,
id: Number
}
]
}
}
});
Use the projection field :
If you want to get all the array :
dbswap.findOne(
{ 'swap.Items.Electro.id':data.id},
{ 'swap.Items.Electro' : 1}
, function(err, obj){
will return something like :
{
_id: ObjectId("sdfsdfsdf"),
Electro:[{....},{....}]
}
Or if you want only the object in the array who match the query :
dbswap.findOne(
{ 'swap.Items.Electro.id':data.id},
{ 'swap.Items.Electro.$' : 1}
, function(err, obj){
will return something like :
{
_id: ObjectId("sdfsdfsdf"),
Electro:{your match object}
}
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 :)
I have the following mongoose schema:
{
name: String,
subArray: [
{
subName: String,
subNumber: Number
}
]
}
I've added objects to the subArray, which get automatically assigned an "_id". In Node.js, how do I find an object by "_id" within the subArray and remove it?
You can se mongoose findOneAndUpdate along with $pull operator. So something like following would work (untested):
Model.findOneAndUpdate( {'subArray._id' : '55a19992474e7ded6b4ae2b0'} ,
{
$pull: { subArray: { _id: '55a19992474e7ded6b4ae2b0' }}
}
{new: true},
function(err, doc){
console.log(err,doc)
})
A small correction for the above code sefgment
ProductContact.findOneAndUpdate({'productRoles._id':req.params.product_role_id},
{
$pull: { productRoles: {_id:req.params.product_role_id }}
},{new:true},
function(err, productcontact) {
if(err)
res.send(err);res.json({message: 'Role successfully deleted.'});
})