how not to show items with specific condition in mongoose - node.js

My code is as shown below:
foodtruck.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Items = require('./items.js');
var FoodTruckSchema = new Schema({
foodtruck_name:String,
foodtruck_location:String,
foodtruck_rating:{type:Number,default:5},
foodtruck_total_votes:{type:Number,default:0},
foodtruck_tag:String,
foodtruck_open_status:{type:Number,default:1}, //0 open 1 closed
foodtruck_starting_timing:String,
foodtruck_closing_timing:String,
foodtruck_cusine:[String],
foodtruck_img:String,
foodtruck_logo:String,
item_list: [ {type : mongoose.Schema.ObjectId, ref : 'items'}]
},{ versionKey: false });
module.exports = mongoose.model('foodtruck',FoodTruckSchema);
items.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ItemSchema = new Schema({
no_of_times_ordered:Number,
item_name:String,
item_tag:String,
item_category:String,
item_description:String,
item_illustrations:[String],
item_stock:Number, //0 available 1 last 5 items 2 not available
item_quantity_ordered:{type:Number,default:0},
item_discount_price:Number,
item_price:Number,
item_img:String,
no_of_likes:{type:Number,default:0}
},{ versionKey: false });
module.exports = mongoose.model('items',ItemSchema);
My query is as show below:
var foodtrucklist = function(req, res) {
foodtr.find().populate('item_list').exec(function(err, foodtrucks) {
foodtrucks.forEach(function(ftr) {
var start_time = ftr.foodtruck_starting_timing;
var end_time = ftr.foodtruck_closing_timing;
var foodtruck_open_status = ftr.foodtruck_open_status;
// var shut_down = ftr.foodtruck_shutdown;
if ((start_time && end_time) &&
(start_time.trim() != '' &&
end_time.trim() != '')) {
if (inTime(start_time, end_time) &&
foodtruck_open_status ==0 ) {
ftr.foodtruck_open_status = 0;
ftr.save();
} else {
ftr.foodtruck_open_status = 1;
ftr.save();
}
}
})
res.json({
status: '200',
message: 'foodtrucklist',
data: foodtrucks
});
});
};
now what I want to achieve is, I don't want to show items which have **item_stock = -1 **. How can I achieve in populate query?

you can use populate options inside your populate (match for query condition).
Try this:
foodtr
.find()
.populate({
path :'item_list',
match : {
item_stock : { $ne : -1}
}).
exec(function(err, foodtrucks) {
...
});
For more information on populate options, read Mongoose populate query condtions and options documentation, look for query condition and options

Related

How to save multiple items in array to database in NodeJS/Mongoose

So first of all im getting a post via a form that returns to me multiple lines of text
then i use the following to split it into multiple urls
var str = req.body.url;
var split = str.split('\n');
then i get this
[urlone,urltwo,urlthree]
my save function works fine for one document
i just cant seem to submit all three at the same time to mongo via mongoose commands .
ive tried a few forEach loops . and got no help
I can really use some help here
I'm really new to nodejs
Define Model:
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let ModelSchema = new Schema(
{
property: String,
urls: []
},
{
collection: 'models',
strict: true,
autoIndex: true
}
);
module.exports = Model = mongoose.model('Model', ModelSchema);
Now, you can create or update any record.
let urlArray = req.body.url.split('\n');
// solution 1
let myModel = new Model();
myModel.property = 'xxx';
myModel.urls = urlArray;
myModel.save();
// solution 2
Model.update({ property: 'xxxx' }, { $set: { urls: urlArray } }, { upsert: true }, function(err, res) {
// continue to check err/res
})
// solution 3, prevent from duplicate entries
Model.update({ property: 'xxxx' }, { $addToSet: { urls: urlArray } }, { upsert: true }, function(err, res) {
// continue to check err/res
})

MongoDB and mongoose: how to add an object if it doesn't already exist

I am having some trouble with mongoDB/mongoose and node.js. I am used to SQL, and mongoDB is...hard! Here is my schema:
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
var itemSchema= mongoose.Schema({
item_info : {
user_id : Number,
location : String,
item_id : Number,
title : String
},
item_hist : {
user_id : Number,
location : String,
item_id : Number,
founddate : String
}
});
module.exports = mongoose.model('item', itemSchema);
And I can add a new item by doing this:
var item= require('./app/models/item');
var item= new item();
item.item_info.user_id = 12345;
item.item_info.location = 'This address';
item.item_info.item_id = 4444;
item.item_info.title = 'New item';
item.save(function(err)
{
if (err) throw err;
});
What I want to be able to do is say: "look for an item with item_info.item_id 5555. if it exists, do nothing. if it doesn't exist, then add it to the database." I've read through so much mongodb and mongoose documentation, but between using dot notation and accessing through nodejs instead of command line mongodb, I still can't figure out how to do this. SQL seemed so much easier!
Just use this -
var query = { user_id: 12345, location: "This address", item_id: 4444, title: "New item" },
options = { upsert: true };
Model.findOneAndUpdate(query.item_id, query, options, function(error, result) {
if (error) return;
// do something with the document
});

Why duplicates are save even if I use compound index? Mongo(Mongoose)

I am trying to save click coordinates on database but if x and y are the same I don't want to save them. Even if I use compound index and do everything by book, it still saves everything. There is similar question on stackoverflow but it doesn't work for my code.
Model, Schema:
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
require('mongoose-double')(mongoose);
var Schema = mongoose.Schema;
var integerValidator = require('mongoose-integer');
var SchemaTypes = mongoose.Schema.Types;
var clickPoint = new Schema({
clicks: [
{
x: {
type: SchemaTypes.Double
},
y: {
type: SchemaTypes.Double
},
value: {
type: Number,
integer: true
}
}
]
});
clickPoint.index({x: 1, y: 1}, {unique: true});
clickPoint.plugin(integerValidator);
clickPoint.plugin(uniqueValidator);
//export model...
module.exports = mongoose.model("ClickPoint", clickPoint);
Model Controller:
var ClickPoint = require('../Models/point');
exports.addPoint = function (click) {
ClickPoint.findOne(function (err, data) {
if(!err) {
if(data) {
data.clicks.push({
x: click.x,
y: click.y,
value: click.value
});
data.save();
}
else {
var entry = new ClickPoint({
x: click.x,
y: click.y,
value: click.value
});
entry.save();
}
}
})
};
Could it be that all the records are stored in an array and as far as I know, index allows to store duplicates in array? If that is the problem than how would I keep objects unique in an array.
You index x & y, while the fields are clicks.x & clicks.y. If you're trying to add unique values to an array, why not use addToSet?

Mongoose sub Docs CastError

I am new to MongoDB and MongooseJS. I'm also new to nodeJs.
I have an Angularjs project using Typescript. This project work with a "container" json, which itself contains some properties and a testList, which is a json object containing some properties and a fileList, containing an itemList.
So it's like this :
export class Container{
data:string="";
testList:Test[];
}
export class Test {
moredata:string="";
fileList:File[];
}
export class File {...}
etc.
I send this JSON to my nodejs server. I'm using bodyparser to get the json from the req.body object.
Server side, my mongoose Schema are exactly like my angularjs classes, so they look like this :
/*************** mongoose schemas **************/
// item.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
Content : {type : Object, default: ''}
});
// file.js
var mongoose = require('mongoose');
var Item = require('./item');
var schema = new mongoose.Schema({
Data : {type : String, default: ''},
ItemList: {type: [Item], default:[]}
});
// test.js
var mongoose = require('mongoose');
var File = require('./file');
var schema = new mongoose.Schema({
Data: {type:String},
FileList: {type:[File], default:[]}
});
// container.js
var mongoose = require('mongoose');
var Test = require('./test');
var schema = new mongoose.Schema({
Name : {type : String, default: '', index:true, unique:true, required: true, dropDups:true},
Test : {type:[Test], default:[]}
});
If I try to create a new Container object (Mongoose object) and assign it the json from req.body, it bugs : CastError.
If I re-create each sub document from JSON and save the main doc, it bugs too : CastError.
I don't know how to achieve this. It worked before but my mongoose schema where using [mongoose.Schema.Types.Mixed] type for sub docs, and not the "real" types. Fact is, with Mixed I had no _id on sub docs, which I want.
Using real sub docs types, I can see in logs that the _id is created, but all the lists are empty.
Here is my nodejs code :
/*************** nodejs **************/
app.post('/api/container', bodyParser.urlencoded({extended:true}), bodyParser({limit:'50mb'}), bodyParser.json(), function(req, res) {
var test = req.body._test;
var testList = [];
var fileList;
var itemList;
var itemObj;
var fileObj;
var testObj;
for(var i in test){
fileList = [];
for(var j in test[i]._fileList){
itemList = [];
for(var k in test[i]._fileList[j]._itemList){
itemObj = new Item({
Content : test[i]._fileList[j]._itemList[k]._content
});
itemList.push(itemObj);
console.log('item pushed : ' + itemObj + ' and length : ' + itemList.length);
// logs gives info OK.
}
fileObj = new File({
Data: locales[i]._fileList[j]._data,
ItemList: itemList
});
fileList.push(fileObj);
console.log('file pushed : ' + fileObj);
// logs gives info NOK. The ItemList is empty : [], instead of a 70+ item list.
}
testObj = new Test({
Data: locales[i]._data,
FileList: fileList
});
testList.push(testObj);
console.log('test pushed : ' + i);
// once again, logs are NOK : the FileList is empty : []
}
// use mongoose to save the project in the database
new Container({
Name : req.body._name.toLowerCase().trim(),
Test: testList
}).save(function(err, container, count){
if(err){
console.log('erreur : ');
console.log(err);
// we enter here as we have this error :
/*
{ [CastError: Cast to undefined failed for value "
{
_id: 5727ebf95a76ff0011374928,
FileList: [],
Data: 'data'
},
{
_id: 5727ebf95a76ff0011374970,
FileList: [],
Data: 'other data'
}" at path "Test"]
message: 'Cast to undefined failed for value "
{ _id: 5727ebf95a76ff0011374928,\n FileList: [],\n Data: \'data\' },
{ _id: 5727ebf95a76ff0011374970,\n FileList: [],\n Data: \'other data\'}"
at path "Test"',
name: 'CastError',
type: undefined,
value: [{"_id":"5727ebf95a76ff0011374928","FileList":[],"Data":"data"},{"_id":"5727ebf95a76ff0
011374970","FileList":[],"Data":"other data"}],
path: 'Test' }
*/
res.status(403).json({error: 'error'});
} else {
console.log('saved ! ');
res.json(container);
}
});
});
I'm not used to post here, I'm more a reader :) Anyway if my post is not appropriated please inform me and I'll move / edit it correctly.
Thanks for your time.
Checked, and working !
So my error was to use the models of my objects in mongoose schema instead of their Schema.
I'm now exporting both models and schema on each object, and using schema for schema definitions, and models for requests. Finally rid of this bug ! :)
/* Mongoose object definitions */
// grab the mongoose module
var mongoose = require('mongoose');
var child = require('./child').schema; // getting the child schema
// define our parent model
var parentSchema = new mongoose.Schema({
Name : {type : String, default: ''},
ChildrenList: {type: [Child], default:[]}
});
var parentModel = mongoose.model('Parent', parentSchema);
// module.exports allows us to pass this to other files when it is called
module.exports = {
model: parentModel, // exporting model for requests
schema: parentSchema // exporting schema for others schema using "Parent"
};
And the code used for requests :
var Child = require('./models/child').model; // here using model
var Parent = require('./models/parent').model; // here using model
new Parent({
Name : req.body._name.toLowerCase().trim(),
ChildrenList : childrenList // variable defined somewhere
}).save(function(err, parent, count){
if(err){
res.status(403).json({error: 'too bad'});
} else {
res.json(parent);
}
});

How to search in sub doc

I have an angular-fullstack app generated from angular-fullstack yeoman generator and I have a Query Model as follows:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Discussion Question Schema
*/
var QuerySchema = new Schema({
date: {
type: Date,
default: Date
},
tags: [{
type: Schema.ObjectId,
ref: 'Tag'
}]
});
module.exports = mongoose.model('Query', QuerySchema);
var deepPopulate = require('mongoose-deep-populate')(mongoose);
and Tag has a field text. Now in my query controller I have to deep populate some other fields and paginate them so, I am trying something like this in the controller function:
exports.index = function(req, res) {
var escapeRegExpChars = function (text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
require('paginate-for-mongoose');
var limit,page;
if(req.query.limit != undefined) limit = req.query.limit;
else limit = 10;
if(req.query.page != undefined) page = req.query.page;
else page = 1;
var queryObj = {};
if(req.query.searchText != undefined && req.query.searchText != '')
queryObj['title']= new RegExp(escapeRegExpChars(req.query.searchText), 'i');
var options = {
perPage:limit,
delta:2,
page:page
};
if(req.query.fold !=undefined && req.query.fold != '') queryObj["tags.text"] = req.query.fold;
var query = Query.find(queryObj).populate('tags','text').deepPopulate('user class user.class');
query.paginate(options,function(err, resp){
if(err) { return handleError(res, err); }
if(req.query.fold) console.log(resp.results);
return res.status(200).json(resp.results);
});
};
How do I search queries with tags.text value exactly as the req.query.fold value?
MongoDB doesn't support joins so to search on a linked doc you have to do it in two steps:
// First look up the _id of the tag
Tags.findOne({text: req.query.fold}, function(err, tag) {
if (tag) {
// Add a match in the doc's tags array to the tag's _id
queryObj.tags = tag._id;
var query = Query.find(queryObj)...
...
}
});

Resources