I am trying to publish a node app to my Raspberrypi (the closest thing I have to a dedicated server XD ) for some of my friends to test a little web-app I wrote, but for some reason one of the queries is not working correctly on the pi when it does on my ide (cloud 9).
Here is the schema:
var campaignSchema = new Schema({
gameMaster: {
type: Schema.Types.ObjectId,
ref: "Users"
},
players: [{
type: Schema.Types.ObjectId ,
ref: "Users"
}],
name: String,
gameSystem: String,
subSystem: String
});
And here is the query:
db.Campaign.findOne({'_id' : req.params.campaign}, 'gameMaster players')
.exec(function(err, campaign){
console.log(campaign);
});
Which results in :
{
_id: 556f09195865094845a0d522,
players: []
}
But doing db.campaigns.find({}) in mongo results in:
{
"_id" : ObjectId("556f09195865094845a0d522"),
"gameMaster" : ObjectId("556d1daf4b9b697213468827"),
"gameSystem" : "Nwodv2",
"subSystem" : "Demon",
"name" : "Baltimore",
"players" : [ ],
"__v" : 0
}
I feel like I must be missing something... I don't have any idea how to resolve this though, I tried the query without a limiter on the fields, but it still omitted the gameMaster field...
Edit: at request here is the creation of the Campaign object
var campaign = new db.Campaign({
gameMaster: userid,
gameSystem: req.body.system,
subSystem: req.body.subsystem,
name: req.body.name
});
To be further confounding, this query works:
db.Campaign.findOne({'_id' : req.params.campaign},
'_id name gameSystem subSystem gameMaster players')
.populate('gameMaster', '_id displayName')
.populate('players', '_id displayName')
.exec(function(err, campaign) {
//gameMaster is valid here with the id and displayName populated...
});
https://github.com/Automattic/mongoose/issues/3020
If anyone else is having this issue. I found this bug report that can explain the cause of the problem, it is related to how you install the new mongoose 4 apparently.
Related
I'm defining a mongoose schema like this
var accountPostSchema = new mongoose.Schema({
account: {
id: { type: mongoose.Schema.Types.ObjectId, ref: 'Account' }
},
post: {
id: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
}
});
app.db.model('AccountPost', accountPostSchema);
When a user(account holder) create a post, I save the post in a Post schema and get the 'postId'. Then I save the 'postId' and the 'accountId'
in the above accountPostSchema like this
var fieldsToSet = {
post: {
id: postId
},
account: {
id: accountId
}
};
db.models.AccountPost.create(fieldsToSet, function(err, accountPost) {
if (err) {
// handle error
}
// handle success
});
After entering few postId's and accountId's, I see the following results in the mongo shell
> db.accountposts.find({})
{ "_id" : ObjectId("5835096d63efc04da96eb71e"), "post" : { "id" : ObjectId("5835096d63efc04da96eb71d") }, "account" : { "id" : ObjectId("5833c920c868d7264111da69") }, "__v" : 0 }
{ "_id" : ObjectId("583509e12052c7a2a93c4027"), "post" : { "id" : ObjectId("583509e12052c7a2a93c4026") }, "account" : { "id" : ObjectId("5833c920c868d7264111da69") }, "__v" : 0 }
Now how do I find all the matching 'Posts' given an accountId? (not the postId's)
For example if I the accountId is 583509e12052c7a2a93c4026, I need to find Posts with Post._id=5835096d63efc04da96eb71d and Post._id=583509e12052c7a2a93c4026
What is the query I should run to get the matching Posts?
I think, you should follow this way to get all the posts associated with particular accountid.
db.accountposts.find({'account.id' : accountId})
.populate('post.id')
.exec();
First, I would suggest changing your Schema to the following
var accountPostSchema = new mongoose.Schema({
account: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Account'
},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
});
This actually makes more sense, especially when you try to populate the subdocuments. Actually, I would say this Schema is useless. Why don't you define your Post schema like the following?
var PostSchema = new mongoose.Schema({
poster: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Account'
},
message: String
});
If you use the latter code, you could execute the following query to get all posts by a particular user:
db.posts.find({poster: accountId}, function(dbErr, userPosts) {
if(dbErr) {
// Handle the error.
}
// Do something with the posts by accountId in the array userPosts.
});
The advantages of removing the id field from poster becomes clear once you try to populate poster. If you defined poster as an object with the field id and try to populate it, you will need to access data about the poster as such:
posterName = retrievedPost.poster.id.name;
Alternatively, by just making the poster field an ObjectId directly, you can access the populated user more directly:
posterName = retrievedPost.poster.name;
this is my scene:
I have 2 collections(tables):Projects and students(the relation is many to many).
My models are:
Project:
var ProjectSchema = new Schema({
name: {
type: String
},
description: {
type: String
},
user : {
type : Mongoose.Schema.Types.ObjectId,
ref : "User"
}
});
Mongoose.model('Project', ProjectSchema);
User:
var Userchema = new Schema({
name: {
type: String
},
surname: {
type: String
},
project : {
type : Mongoose.Schema.Types.ObjectId,
ref : "Project"
}
});
Mongoose.model('User', UserSchema);
In my view I have 2 inputs where receive name and description of project, then have multiselect where choose 1 or multiples users for this project. When I Click OK should:
Create project, and add to user all users selected as objects in BBDD.
Update user, with project asociation.
I try the next, but only funcion if I choose 1 user:
exports.addUserProject = function(req, res) {
var project=new svmp.Project();
project.name=req.body.name;
project.description=req.body.description;
project.user=req.body.user[0]._id;
project.save(function(err,project){
if (err) {
return res.send(400, {
message : getErrorMessage(err)
});
} else {
res.jsonp(project);
}
})
};
The result in my BBDD is the next:
{ "_id" : ObjectId("57a200a38fae140913ac5413"), "user" : ObjectId("578f41ddb0641d961416c3f5"), "name" : "Project1", "Description" : "Project1 Desc","__v" : 0 }
Thanks for your help
First in your schema definition, since the relationship is many-to-many, you should change the ref to an array of the referenced objects. For example change the user property of projectSchema to an array of object ids like so,
var ProjectSchema = new Schema({
name: {
type: String
},
description: {
type: String
},
user : [{
type : Mongoose.Schema.Types.ObjectId,
ref : "User"
}]
});
Do the same for the project property of the userSchema.
Secondly, on this line project.user=req.body.user[0]._id; you are setting the the _id of only the first selected user as the user while ignoring every other selected users. This is why your code only works for one user. Instead, I will suggest you use a simple loop to push all selected users' _id to the project's user property. You can use a forEach loop as given below.
var selectedUsers = req.body.user;
selectedUsers.forEach(function(u){
project.user.push(u._id)
})
You can also do this with a simple for loop if you wish.
I believe the suggestions above should fix the issues you described.
It might be conceptual question about _id in mongodb.
I understand mongodb will insert a _id field automatically if you don't set key field in document.In my case, I defined a field as Object Array, I don't know why it always create a _id in each Object in Array of this field.
I do appreciate if someone could clarify it for me.
Mongoose Model Scheme definition:
module.exports = mongoose.model("Application", {
Name: String,
Description: String,
Dependency: [
{
App_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Application'
},
Priority: Number
}
]
});
This is an Update operation, request data is:
{ _id: '571953e33f33c919d03381b5',
Name: 'A Test Utility (cmd)',
Description: 'A Test Utility (cmd)'
Dependency:
[ { App_id: '571953e33f33c919d03381b6', Priority: true },
{ App_id: '571953e33f33c919d03383da', Priority: 0 } ]
}
I use this code to update it
var id = req.body._id;
Application.findOneAndUpdate({ _id: id }, req.body, function (err, app) {
if (err)
res.send(err);
res.json(app);
});
The update is successful.But the document in mongodb is:
{
"_id" : ObjectId("571953e33f33c919d03381b5"),
"Name" : "A Test Utility (cmd)",
"Description" : "A Test Utility (cmd)",
"Dependency" : [
{
"Priority" : 1,
"App_id" : ObjectId("571953e33f33c919d03381b6"),
"_id" : ObjectId("571a7f552985372426509acb")
},
{
"Priority" : 0,
"App_id" : ObjectId("571953e33f33c919d03383da"),
"_id" : ObjectId("571a7f552985372426509aca")
}
]
}
I just don't understand how come the _id in the "Dependency" Array?
Thanks.
When you use [{..}] that means inside it act as a sub schema and you know that MongoDB insert a _id field automatically if you don't set key field in document. So you need to force to insert document without _id field.
Need use {_id:false} for your Dependency array schema to insert without _id
var ApplicationSchema = new mongoose.Schema({
Name: String,
Description: String,
Dependency: [
{
App_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Application'
},
Priority: Number,
_id: false
}
]
});
module.exports = mongoose.model("Application", ApplicationSchema);
I've got the following schema
var UserSchema = new Schema({
emp_no: Number,
skills: [{
skill: {
type: Schema.Types.ObjectId,
ref: 'Skill'
},
startDate: {type: Date},
}]
});
I'm then trying to update the startDate of one particular skill. I've tried several differents ways, one of them being:
User.findOne({emp_no: req.body.emp_no}, function (err, user) {
user.update( {'skills._id': 123}, {'$set': {
'skills.$.startDate': req.body.startDate
}}
}
This particular code gives: err: 'cannot use the part (skills of skills._id) to traverse the element
The actual object looks like
{
"_id" : ObjectId("5469753de27a7c082203fd0a"),
"emp_no" : 123,
"skills" : [
{
"skill" : ObjectId("547d5f3021d99d302079446d"),
"startDate" : ISODate("2014-12-02T06:43:27.763Z")
"_id" : ObjectId("547d5f8f21d99d3020794472")
}
],
"__v" : 108
}
Any ideas what I'm doing wrong?
When you call update on a model instance like you're doing here, the first parameter is the update operation to apply to that document, as the document to update is already uniquely identified by its _id.
Instead, use Model.update to do this all in one operation:
User.update(
{emp_no: req.body.emp_no, 'skills._id': 123},
{'$set': {
'skills.$.startDate': req.body.startDate
}},
function(err, numAffected) {...}
);
I am trying to implement FTS feature with node and mongdodb backend. In the search result, I would also like to project a new field, i.e the matched string in the document. This would give it a google like feel. Has anyone got ideas on this without having write lots of own custom functions?
The schema looks like this
var version = new mongoose.Schema({
name: String,
owner: String,
reviewer: String,
date_of_modification: Date,
comments: String,
hints: [String],
global: Boolean,
**content: { type: [String], index: true }**
version_no: Number,
});
var artifactSchema= new mongoose.Schema({
pid : String,
trashed : Boolean,
baseline : Number,
versions : [version],
});
I would like to create an index on the content field of Version model.
I know its a little late but recently I did it with MEAN+angucomplete
AngularJS Query e.g. http://localhost:8080/api/search?s=
Express Query
router.route('/search')
.get(function(req, res) {
Dept.aggregate(
{ $match : { 'Product.name' : new RegExp(query, 'gi') } },
{ $project : { name : 1, _id : 1, 'Product.name' : 1, 'Product._id' : 1} },
{ $unwind : "$Product" },
{ $group : {
_id : "$_id",
Category : { $addToSet : "$name"},
Product : { $push : "$Product"}
}}
)
});
Angucomplete Markup
<div angucomplete-alt id="depts"
placeholder="Click Here to Search across Whole Store"
pause="300"
selected-object="selectedDepts"
remote-url="http://localhost:8080/api/search?s="
remote-url-data-field="Departments"
remote-url-response-formatter="responseFormatted"
search-fields="name"
title-field="name"
minlength="1"
maxlength="20"
description-field="description"
override-suggestions="true"
match-class="highlight"
autocapitalize="on" autocorrect="off" autocomplete="off"
input-class="form-control form-control-small"
class="col-lg-8"
ng-pattern="/^[A-Za-z]+$/"
docs-search-input-focus
>
</div>