Populate not working for an array of ObjectIDs - javascript

This is the implementation of my models :
var itemSchema = new Schema({
name : String,
qte : Number
});
var Item = mongoose.model('Item', itemSchema);
var orderSchema = new Schema({
state : {
type: String,
enum: ['created', 'validated', 'closed', 'starter', 'meal', 'dessert'],
required : true
},
table : {
number : {
type : Number,
required : true
},
name : {
type : String,
required : false
}
},
date: { type: Date, default: Date.now },
_items : [{type:Schema.Types.ObjectId, ref:'Item'}]
});
And this is how I do my query
getByIdRaw : function (orderId, callback) {
Order.findById(orderId)
.populate('_items')
.exec(function(err, order) {
debug(order);
callback(order);
});
}
This is my response without populating
{
_id: "5549e17c1cde3a4308ed70d5"
state: "created"
_items: [1]
0: "5549e1851cde3a4308ed70d6"
-
date: "2015-05-06T09:40:12.721Z"
table: {
number: 1
}-
__v: 1
}
...and my response when populating _items
{
_id: "5549e17c1cde3a4308ed70d5"
state: "created"
__v: 1
_items: [0]
date: "2015-05-06T09:40:12.721Z"
table: {
number: 1
}-
}
Why the _items array is empty ? What am I doing wrong ?
EDIT : the addItem function
addItem : function (orderId, item, callback) {
Order.findById(orderId)
.exec(function(err, order) {
if (err) {
error(err);
return callback(err);
}
if (order === null) {
return callback("No order with this id");
}
var newItem = new Item({
name : item.name,
qte :item.qte
});
order._items.push(newItem);
order.markModified('_items');
order.save();
callback();
});
}

The issue is the new item is never persisted to the items collection. Mongoose references only populate they don't persist a new item to the referenced collection.
addItem: function(orderId, item, callback) {
var newItem = new Item({
name: item.name,
qte: item.qte
});
newItem.save(function(err, savedItem) {
if (err) {
error(err);
return callback(err);
}
Order.findById(orderId).exec(function(err, order) {
if (err) {
error(err);
return callback(err);
}
if (order === null) {
return callback("No order with this id");
}
order._items.push(savedItem);
order.markModified('_items');
order.save(callback);
});
});
}

Related

Issue in document insert using mongoose

I have schema created now i want to insert into mongodb collection, but its throwing error diagramModel.insert is not defined any idea what is implemented wrong ?
app.js
mongoose.connect('mongodb://localhost:27017/develop-modeler');
require('./server/api/diagram/diagram.model.js');
var diagramModel = mongoose.model('Diagram');
var newDiagram = {
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
}
mongoose.connection.on('connected', function () {
diagramModel.insert(newDiagram,function(err,res){
if (err) { console.log(err);}
else {
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});
diagram.model.js
var DiagramSchema = new mongoose.Schema({
text: String,
owner: {type: String, ref:'User'},
groups: [{type: String, ref: 'Group'}],
users: [{type: String, ref: 'User'}],
string: String
});
mongoose.model('Diagram', DiagramSchema);
I think it's save not insert while saving records. That's why you are getting this error
mongoose.connect('mongodb://localhost:27017/develop-modeler');
var diagramModel = require('./server/api/diagram/diagram.model.js');
var newDiagram = {
"owner": "sh529u",
"text": "sco_poc.bpmn",
"users": ["wp6307", "kz323j", "ew6980"],
"groups": [],
"string": "test"
}
mongoose.connection.on('connected', function() {
diagramModel.save(newDiagram, function(err, res) {
if (err) {
console.log(err);
} else {
diagramModel.find({}, function(err, data) {
console.log(data);
});
}
});
});
var DiagramSchema = mongoose.Schema({
text: String,
owner: {type: String, ref:'User'},
groups: [{type: String, ref: 'Group'}],
users: [{type: String, ref: 'User'}],
string: String
});
module.exports=mongoose.model('Diagram', DiagramSchema);
Create a new instance of your model and this instance contains a save method:
mongoose.connect('mongodb://localhost:27017/develop-modeler');
require('./server/api/diagram/diagram.model.js');
var diagramModel = mongoose.model('Diagram');
var newDiagram = new diagramModel({
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
});
mongoose.connection.on('connected', function () {
newDiagram.save(function(err,res){
if (err) { console.log(err);}
else {
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});
Try this its working perfect
var diagramModel = require('./server/api/diagram/diagram.model.js');
var finalDiagram = diagramModel({
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
});
mongoose.connection.on('connected', function () {
finalDiagram.save(function (err, dataObj) {
if (err) { console.log(err);}
} else {
console.log("DATA",dataObj);
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});

GraphQL, Mysql equivalent OR operation

I have just learnt GraphQL and I want to find the user id=2 OR user id=3 now how will I make the GraphQL query,I am getting the whole set using the bellow query
{
users() {
id
username
posts {
title
tags {
name
}
}
}
}
2nd issue --
{
people(id:[1,2,3]) {
id
username
posts(id:2) {
title
tags {
name
}
}
}
}
if I add the arg on Posts filed then i got an error msg "Unknown argument id on field posts of type user"
This is my Schema js file
var graphql = require('graphql');
var Db = require('./db');
var users = new graphql.GraphQLObjectType({
name : 'user',
description : 'this is user info',
fields : function(){
return {
id :{
type : graphql.GraphQLInt,
resolve(user){
return user.id;
}
},
username :{
type : graphql.GraphQLString,
resolve(user){
return user.username;
}
},
posts:{
id:{
type : graphql.GraphQLString,
resolve(post){
return post.id;
}
},
type: new graphql.GraphQLList(posts),
resolve(user){
return user.getPosts();
}
}
}
}
});
var posts = new graphql.GraphQLObjectType({
name : 'Posts',
description : 'this is post info',
fields : function(){
return {
id :{
type : graphql.GraphQLInt,
resolve(post){
return post.id;
}
},
title :{
type : graphql.GraphQLString,
resolve(post){
return post.title;
}
},
content:{
type : graphql.GraphQLString,
resolve(post){
return post.content;
}
},
person :{
type: users,
resolve(post){
return post.getUser();
}
},
tags :{
type: new graphql.GraphQLList(tags),
resolve(post){
return post.getTags();
}
}
}
}
});
var tags = new graphql.GraphQLObjectType({
name : 'Tags',
description : 'this is Tags info',
fields : function(){
return {
id :{
type : graphql.GraphQLInt,
resolve(tag){
return tag.id;
}
},
name:{
type : graphql.GraphQLString,
resolve(tag){
return tag.name;
}
},
posts :{
type: new graphql.GraphQLList(posts),
resolve(tag){
return tag.getPosts();
}
}
}
}
});
var query = new graphql.GraphQLObjectType({
name : 'query',
description : 'Root query',
fields : function(){
return {
people :{
type : new graphql.GraphQLList(users),
args :{
id:{type: new graphql.GraphQLList(graphql.GraphQLInt)},
username:{
type: graphql.GraphQLString
}
},
resolve(root,args){
return Db.models.user.findAll({where:args});
}
},
posts:{
type : new graphql.GraphQLList(posts),
args :{
id:{
type: graphql.GraphQLInt
},
title:{
type: graphql.GraphQLString
},
},
resolve(root,args){
return Db.models.post.findAll({where:args});
}
},
tags :{
type : new graphql.GraphQLList(tags),
args :{
id:{
type: graphql.GraphQLInt
},
name:{
type: graphql.GraphQLString
},
},
resolve(root,args){
return Db.models.tag.findAll({where:args});
}
}
}
}
});
var Mutation = new graphql.GraphQLObjectType({
name : "mutation",
description : 'function for mutaion',
fields : function(){
return {
addPerson : {
type : users,
args :{
username : {
type : new graphql.GraphQLNonNull(graphql.GraphQLString)
},
email :{
type : new graphql.GraphQLNonNull(graphql.GraphQLString)
}
},
resolve(_, args){
return Db.models.user.create({
username : args.username,
email : args.email
});
}
}
}
}
})
var Schama = new graphql.GraphQLSchema({
query : query,
mutation : Mutation
})
module.exports = Schama;
In order to fetch multiple data from your schema using an array of ids you should define the args given to the users in your schema as follows:
fields: () => ({
users: {
type: new GraphQLList(USER_GRAPHQL_OBJECT_TYPE),
args: {
id: {type: new GraphQLList(GraphQLInt)}
},
resolve: (root, args) => {
// fetch users
}
}
})
notice the new GraphQLList wrapping the GraphQLInt type of the id.
Then, when querying your schema you can :
{
users(id: [2, 3]) {
id
username
posts {
title
tags {
name
}
}
}
}
Please let me know if it was helpful :)

Sails.js query db by foreign key

I'm wondering how to make a query by foreign key using the default Waterline model.
I have two models Post and Category - Post has a foreign key category. I need to make a query like so:
Post.find({
where: {
category: query
}
}).exec(function (err, data) {});
In this case query is a string so the results returned should be Posts containing searched category.
What is the best way to do this?
Note: Current example does not work
Your model should be
// Post
module.exports = {
attributes: {
name: {
type: 'string'
},
category: {
model: 'category'
}
}
};
// Category
module.exports = {
attributes: {
name: {
type: 'string'
},
post: {
collection: 'Post',
via: 'category'
}
}
};
Then query from category would be
Category
.find()
.where({ name: query })
.populateAll()
.exec(function (error, categories) {
var catArr = [];
if (categories.length) {
categories.map(function (item) {
catArr.push(item.id);
});
}
Post.find().where({ category: catArr }).exec(function (error, posts) {
// do stuff
});
});
Or simply you can query it from post by
Post
.find()
.where({ category: categoryId })
.populateAll()
.exec(function (error, posts) {
// posts is all post with category that defined
});
Make sure that you know categoryId if you want to query it from post. I usually use categoryId is string and slugify from name, so I can query category by it's name and make sure that category name (and also ID of course) is unique.
Figured how to implement this using the category id:
Category.find().where({ name: query }).exec(function (error, categories) {
var catArr = [];
if (categories.length) {
categories.map(function (item) {
catArr.push(item.id);
});
}
Post.find().where({ category: catArr }).exec(function (error, posts) {
// do stuff
});
});
Also had to add attributes in the models like so:
// Post
module.exports = {
attributes: {
name: {
type: 'string'
},
category: {
model: 'category'
}
}
};
// Category
module.exports = {
attributes: {
name: {
type: 'string'
},
post: {
model: 'post'
}
}
};

Why my mongoose objectId request return an empty array?

I past my day to find the answer, in vain.
this is my mongoose schema:
var schema = new mongoose.Schema({
value: {type: String},
title: {type: String},
date: { type: Date, default: Date.now },
packId: {type: mongoose.Schema.Types.ObjectId, ref:'Pack'}
});
this is my request:
( Where packId is a ObjectId )
var getElements = function(packId, callback ){
Card.find(
{packId: packId},
function(err,els){
if(err){
console.log(err);
}else{
console.log(els);
}
}
);
};
**And this is a table element **
{
"title" : "test1",
"value" : "test1",
"packId" : ObjectId("54f9ebaae312727c45b2a80e"),
"_id" : ObjectId("54f9ebaae312727c45b2a820"),
"date" : ISODate("2015-03-06T18:02:18.544Z"),
"__v" : 0
}
I don't understand why the console.log(els) return [], because there is elements in table. I've tried whith {type: Sting} but nothing at all.
Thanks
OK, i've found the reason.
models.Card.saveCards(completeData.cards,packData.cid, function(){
models.Card.getCards(packData.cid,function(cards){
...
}
}
the second method getCards is called before all cards are saved.
So this is how i did
var saveCards = function( cardsData, packId, callback ){
var nbCards = cardsData.length;
var start = 0;
var saveCard = function(cardData,packId) {
cardData.packId = packId;
var card = new Card(cardData);
card.save(function (err, card) {
if (err) {
console.log(err);
} else {
if(start<nbCards-1){
start++;
saveCard(cardsData[start],packId);
}else{
callback();
}
}
});
};
if( start === 0){
saveCard(cardsData[start],packId);
}
};
hope this helps

Add more fields in MapReduce with Mongoose and NodeJS

I've this mongoose schema
var SessionSchema = mongoose.Schema({
id: Number,
cure: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Cure'
},
performances: Array,
startDate: Date,
endDate: Date,
validatee: Boolean,
deleted: Boolean
});
I need to know how many documents have different ids, but i only need those that have startDate greater than a given date (for example today).
Running the following code works fine but i want to add some fields in map to use them in the query.
var o = {};
o.map = function () {
emit(this.id, 1
// list other fields like above to select them
)
}
o.reduce = function (k, vals) {
return vals.length
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime)
console.log("MapReduce" + JSON.stringify(model));
model.find().exec(function (err, docs) {
console.log(docs);
});
});
This is my output :
[ { _id: 0, value: 2 },
{ _id: 1, value: 4 },
{ _id: 2, value: 2 } ]
I try to do this:
....
o.map = function () {
emit(this.id, {
startDate: this.startDate
})
}
....
model.find({
startDate: {
"$gte": new Date()
}
}).exec(function (err, docs) {
console.log(docs);
});
....
but I keep getting the same output.
So how do I add more key-value params from the map function to the result dictionary of the reduce function?
This is a solution :
var o = {};
o.map = function () {
emit(this.id, {
startDate: this.startDate,
cure: this.cure,
test: 'test'
// list other fields like above to select them
})
}
o.reduce = function (k, vals) {
return {
n: vals.length,
startDate: vals[0].startDate,
cure: vals[0].cure,
test: vals[0].test
}
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime);
model.find({
'value.cure':mongoose.Types.ObjectId('52aedc805871871a32000004'),
'value.startDate': {
"$gte": new Date()
}
}).exec(function (err, docs) {
if(!err)
console.log(docs.length);
});
});

Categories

Resources