I have left my code for over a year and have ran NPM install and since it obviously has changed :)
My Query
var mongoose = require('mongoose'),
Clubs = mongoose.model('Clubs');
getNorsemanClubs: function(passData){
return new Promise(function (resolve) {
Clubs.find({norseman:true}, 'name teamID date norseman eleven').sort({ eleven : 'asc'})
.then(function(clubs){
console.info(clubs);
passData.clubs = clubs;
resolve(passData);
});
})
}
console.info(clubs); Output
Here you can see that it is returning the model rather than the results of the clubs.
My model
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
/**
* User Schema
*/
var ClubsScheme = new Schema({
name: String,
teamID: { type: String, default: null },
date: { type: Date, default: Date.now},
norseman: {type: Boolean, default: false},
eleven: Number
})
mongoose.model('Clubs', ClubsScheme);
How can I get it return a list of the clubs?
The clubs table is full of match data. But I used to get a return from 'name teamID date norseman eleven' now I just get a return of :\
**Using exec()
You need to execute your find mongoose query method, by trailing your query with exec() method so that it return a Promise with your list values resolved, so change the following line:
Clubs.find({norseman:true}, 'name teamID date norseman eleven').sort({ eleven : 'asc'})
to:
Clubs.find({norseman:true}, 'name teamID date norseman eleven').sort({ eleven : 'asc'}).exec()
Related
I am designing a character sheet app for a tabletop RPG.
I have a character schema and an item schema created using Mongoose.
The character schema has a property called equippedItems which is an array of item subdocuments that represent what the character currently has equipped.
I want to add a virtual to the character schema called 'currentLoad' that gets the 'load' value from each item in equippedItems and adds them together to get the total weight of the character's currently equipped items.
How would I go about using mongoose's .virtual() to accomplish this?
Character Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const characterSchema = new Schema({
... //lots of other fields
equippedItems: [
{
type: Schema.Types.ObjectId,
ref: 'Item'
}
],
});
characterSchema.virtual('currentLoad')
//code to get load values from equippedItems, add together, then set the total to currentLoad
.get()
.set()
const Character = mongoose.model('Character', characterSchema);
module.exports = Character;
Item Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const itemSchema = new Schema({
name: {
type: String,
required: true,
trim: true
},
load: {
type: Number,
required: true,
min: 0,
max: 3
},
});
const Item = mongoose.model('Item', itemSchema);
module.exports = Item;
This question already has answers here:
How do I do greater than/less than using MongoDB?
(3 answers)
Closed 5 years ago.
I have a collection of JSON objects that all have a timestamp. This is my model:
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PriceSchema = new Schema({
high: {
type: Number
},
last: {
type: Number
},
timestamp: {
type: Number
},
bid: {
type: Number
},
vwap: {
type: Number
},
volume: {
type: Number
},
low: {
type: Number
},
ask: {
type: Number
},
open: {
type: Number
}
});
module.exports = mongoose.model('Prices', PriceSchema);
Now I want to write a method that will search the database for all the entries corresponding to the current day. So I check the current time, and then query everything that is older than yesterday:
'use strict';
var mongoose = require('mongoose'),
moment = require('moment'),
Price = mongoose.model('Prices');
exports.list_current_day = function(req, res) {
var now = moment().valueOf()
var oneDayAgo = now - 86400000
Price.findOne({ 'timestamp' > oneDayAgo }, function (err, price) {
if (err) return handleError(err);
res.json(price)
})
}
But my condition is failing. I get Unexpected token >. How do I specify the condition of my search query to return everything with timestamp > currentDay?
Your query is off. findOne takes an object as the first argument describing a property of the target document. The reason you get the error is that a < token is invalid inside an object literal and is invalid syntax. Instead, try the following:
Price.findOne({
timestamp: {
$gt: oneDayAgo
}
}, function (err, price) {
if (err) return handleError(err);
res.json(price)
});
This will use the $gt operator in the query to check if the certain property meets the requirement. Per the MongoDB documentation:
$gt
Syntax: {field: {$gt: value} }
$gt selects those documents where the value of the field is greater than (i.e. >) the specified value.
Thus, it will select documents in which the timestamp field is greater than oneDayAgo.
Is it possible to perform a query within the same schema?
For example, If I have a schema which has 2 date fields, and I need to find the data where one Date field is greater than the other.
This is my schema and code sample.
var Schema = mongoose.Schema;
var someSchema = new Schema({
someId : { type: String, default: '' ,index:true, unique: true },
userName : { type: String, default: ''},
fullName : { type: String, default: '' },
created : {type: Date, default:''},
lastUpdated : {type: Date, default:''},
primaryGroupId : {type:String,default:''},
nextHearing : {type: Date, default:''},
status : {type:String,default:'open'},
});
mongoose.model('Problem', someSchema);
The below code is my query.
var problemModel = mongoose.model('Problem');
var today = Date.now();
problemModel.find({$and:[{'nextHearing':{$lte: today}},{'nextHearing':{$gte : 'lastUpdated'}}]},function(err, result){
When I run the program, I get the following error
{ message: 'Cast to date failed for value "lastUpdated" at path "nextHearing"',
name: 'CastError',
type: 'date',
value: 'lastUpdated',
path: 'nextHearing' }
new Date() returns the current date as a Date object. The mongo shell wraps the Date object with the ISODate helper. The ISODate is in UTC.
so you may need to change:
var today = Date.now();
to
var today = new Date().toISOString();
Also, take a look at this
I'm working on an upvoting/downvoting application using MongoDB and Node.JS
I have created two interlinked schemas:
var mongoose = require('mongoose');
var Voters = require('./voters');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
voters: [Voters.schema],
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
mongoose.model('Post', PostSchema);
and for voters:
var mongoose = require('mongoose');
var votersSchema = new mongoose.Schema({
voter_id: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
votetype: Number
});
module.exports = mongoose.model('Voters', votersSchema);
For including users in the voters array, I'm using this code:
var voterModel = new Voters();
voterModel.voter_id = req.payload._id;
voterModel.votetype = 1;
foundPost.voters.push(voterModel);
foundPost.save();
Which works just fine. For removing users I tried several methods, but none seem to work. The current one is $pull:
foundPost.update({'voters.voter_id': req.payload._id}, {$pull: {'voters': {'voter_id': req.payload._id, 'votetype': 1}}}, function(err){
if (err) { console.log(err); }
});
The update action works in the mongo shell, but not from within node. I also tried foundPost.voters.remove, but the result was the same. Also tried Voters.findOne, but the query always returns null.
Any help would be appreciated.
Use the id method first to find the voter then remove it and last save document to apply changes:
var voter = foundPost.voters.id(req.payload._id).remove();
foundPost.save(function (err) {
if (err) return handleError(err);
console.log('the voter was removed')
});
How can I add a schema to another schema? This doesn't seem to be valid:
var UserSchema = new Schema({
name : String,
app_key : String,
app_secret : String
})
var TaskSchema = new Schema({
name : String,
lastPerformed : Date,
folder : String,
user : UserSchema
})
I checked the website and it shows how to declare it for an array but not for single.
Thanks
There are a few ways to do this. The simplest is just this:
var TaskSchema = new Schema({
name : String,
lastPerformed : Date,
folder : String,
user : Schema.ObjectId
});
Then you just have to make sure your app is writing that id and using it in queries to fetch "related" data as necessary.
This is fine when searching tasks by user id, but more cumbersome when querying the user by task id:
// Get tasks with user id
Task.find({user: user_id}, function(err, tasks) {...});
// Get user from task id
Task.findById(id, function(err, task) {
User.findById(task.user, function(err, user) {
// do stuff with user
}
}
Another way is to take advantage of Mongoose's populate feature to simplify your queries. To get this, you could do the following:
var UserSchema = new Schema({
name : String,
app_key : String,
app_secret : String,
tasks : [{type: Schema.ObjectId, ref: 'Task'}] // assuming you name your model Task
});
var TaskSchema = new Schema({
name : String,
lastPerformed : Date,
folder : String,
user : {type: Schema.ObjectId, ref: 'User'} // assuming you name your model User
});
With this, your query for all users, including arrays of their tasks might be:
User.find({}).populate('tasks').run(function(err, users) {
// do something
});
Of course, this means maintaining the ids in both places. If that bothers you, it may be best to stick to the first method and just get used to writing more complex (but still simple enough) queries.
As of version 4.2.0, mongoose supports single subdocuments.
From the docs:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
What about this simple solution?
var TaskSchema = new Schema({
name : String,
lastPerformed : Date,
folder : String,
user : {
name : String,
app_key : String,
app_secret : String
}
})