Inserting into array error in Mongoose - node.js

This is my MongoDB schema, Seems like push operator is not working
locationCoordinate : {
type : [Number],
index: '2d'
},
i am getting Post data from frontend in my Node.js server which is having Longitude and Latitude
var event = new Events({})
(Events is the name of Schema )
I want to push into this array,
so this seems not to be working
Error on this line
event.locationCoordinate.push(req.body.longitude);
event.locationCoordinate.push(req.body.latitude);
And then saving this by
event.save(function(err,result)){
}
The result may be something like
locationCoordinate[1,2]

var array = [];
array.push({"lng":req.body.longitude},{"lat":req.body.latitude}); // or
array.push(req.body.longitude,req.body.latitude); //just try mybe work
var Evnt = new Events()
Evnt.type = array;
Evnt.index = req.body.index;
Evnt.save(function(...){ ... });

Related

how to query mongoDb with array of boolean fields?

My mongoose model schema looks like -
{
email: { type: String},
Date: {type: Date},
isOnboarded: {type: Boolean},
isVip: {type: Boolean},
isAdult: {type: Boolean}
}
In my frontend I have 3 checkboxes for "isVip", "isOnboarded" and "isAdult" options. If they are checked I'm adding them to an array, which I'll pass to the server. Let's say if "isVip" and "isAdult" are checked, I will pass [isVip, isAdult] in post api to server. Now how can I write a query to get all the documents with the fields in array as true i.e in above example how can I retrieve all docs with {isVip: true, isAdult:true}
I'm having trouble because the array values keep changing, it can be only one field or 3 fields. I couldn't find a way to give condition inside mongoose query.
User.find(
{ [req.query.array]: true},
{ projection: { _id: 0 } }
)
User is my mongoose model.
I want something like this (documents with the value 'true' for the fields given in the array) and 'req.query.array' is the array with field names I passed from frontend.
You have to create your object in JS and pass then to mongo in this way:
var query = {}
if(isVip) query["isVip"] = true;
if(isOnboarded) query["isOnboarded"] = true;
if(isAdult) query["isAdult"] = true;
And then you can use the mongoose method you want, for example:
var found = await model.find(query)
And this will return the document that matches the elements.
Also, note that this is to create and object to be read by the query, so you can use this into an aggregation pipeline or whatever you vant
Check the output:
var query = {}
query["isVip"] = true;
query["isOnboarded"] = true;
query["isAdult"] = true;
console.log(query)
Is the same object that is used to do the query here
{
"isVip": true,
"isOnboarded": true,
"isAdult": true
}
Also, to know if your post contains "isVip", "isOnboarded" or "isAdult" is a javascript question, not a mongo one, but you can use something like this (I assume you pass a string array):
var apiArray = ["isVip","isAdult"]
var isVip = apiArray.includes("isVip")
var isAdult = apiArray.includes("isAdult")
var isOnboarded = apiArray.includes("isOnboarded")
console.log("isVip: "+isVip)
console.log("isAdult: "+isAdult)
console.log("isOnboarded: "+isOnboarded)

Mongoose Bulk upsert not working

Hi i am new to nodejs and mongoose. Just trying to update mongo data with bulk inserts with following methods.
"use strict";
var mongo = require('../models/tracking_mongo');
var Schema = mongo.trackingMasterMongoosePoc.Schema;
//create a schema
var userwise_tracking_events = new Schema({
activities : {},
summary : {},
userId : Number,
counter : Number,
created : Date,
modified : Date
});
let collection = 'userwise_tracking_events';
let UserwiseTrackingEvents = mongo.trackingMasterConnPoc.model(collection, userwise_tracking_events);
UserwiseTrackingEvents.updateCollectionStream = function(condition, params, options, callback){
var Bulk = UserwiseTrackingEvents.collection.initializeUnorderedBulkOp();
Bulk.find(condition).upsert().update(params);
Bulk.execute(callback);
};
module.exports = UserwiseTrackingEvents;
Upper code works fine but this didn't solved my problem for using bulk inserts.
Then i just made a change by making the bulk variable global.
"use strict";
var mongo = require('../models/tracking_mongo');
var Schema = mongo.trackingMasterMongoosePoc.Schema;
//create a schema
var userwise_tracking_events = new Schema({
activities : {},
summary : {},
userId : Number,
counter : Number,
created : Date,
modified : Date
});
let collection = 'userwise_tracking_events';
let UserwiseTrackingEvents = mongo.trackingMasterConnPoc.model(collection, userwise_tracking_events);
var Bulk = UserwiseTrackingEvents.collection.initializeUnorderedBulkOp();
UserwiseTrackingEvents.updateCollectionStream = function(condition, params, options, callback){
Bulk.find(condition).upsert().update(params);
Bulk.execute(callback);
};
module.exports = UserwiseTrackingEvents;
Now getting the error find of undefined is not a function.
When i checked
console.log(UserwiseTrackingEvents.collection);
Gave me result with NativeCollection.collection is null.
Do let me know what i am doing wrong.
I have another methods to work on this but i specifically want what i am doing wrong in this question.
Thanks :)
I would venture to say that your declaration of Bulk is not outside of any function declaration when moved out of the function call. Thus when the exposed function is called , Bulk was not initialized.

Dynamic URL with mongo method

Regarding these post : Mongoose prototype : how to insert an url dynamically?
I'm looking to do pretty much the same (URI dynamically insert).
The solution provided is good but I do not understand some things...
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PicturesSchema = new Schema({
album : { type : String, required : true, trim : true },
pictures : { type : Array, required : false, trim : true }
});
PicturesSchema.virtual('pictureUrls').get(function() {
return this.pictures.map(function(picture) {
return 'https://s3.amazonaws.com/xxxxx/'+ picture;
});
});
var Pictures = mongoose.model('Pictures', PicturesSchema);
// Demo:
var pictures = new Pictures({
album : 'album1',
pictures : [
'1434536659272.jpg',
'1434536656464.jpg',
'1434535467767.jpg'
]
});
console.log( pictures.getPics() );
The given solution injects a "virtual field" in addition to retaining the "pictures" field with the name of the images (without URL).
How to retain only the field "PicturesURL" containing the full URL of the image without displaying a redundancy with the "Pictures" field?
How to retrieve and display the JSON format query results as it knowing that data.ToJson returns an error: has no method 'toJson'?
Pictures.find().exec(function(err, data){
if(err){
console.log(err);
}
console.log('%j', data.toJSON({ virtuals : true }) );
});
A strategy to store only the picture url without the picture would be to create a Mongoose middleware on save.
You could then populate the picture field with the name of the picture, and the full url will be the one stored in the database and later retrieved.
For example:
PictureSchema.pre('save', function (next){
if (this.isModified(pictureUrls){
this.pictureUrls = this.pictureUrls.map(function(picture){
return 'https://s3.amazonaws.com/xxxxx/'+ picture;
})
}
});
With this solution, every time you modify the pictures array, it will go over every element of the array and add the s3 path.
Since it won't be a virtual, it will be easier for you to use the model with event using toObject or toJson.

mongoose, getting object's id after using collection.insert

I'm trying to get the object id after adding it to the db (using collection.insert)
mongoose.model('Persons').collection.insert(person, function(err, newPerson) {
console.log('lets see you', newPerson);
});
and from the console I'm getting only result: { ok: 1, n: 1 } in stand of the new obj, any ideas how can I rich to the new object ?
thanks!
You can use save() here
var Persons = mongoose.model('Persons');
var personJSON = {
..... // persons schema values you want to insert
};
var person = new Persons(personJSON);
var result = yield person.save();
result variable will contain all the fields you inserted along with _id

Why are mongoose references turning into IDs?

According to http://mongoosejs.com/docs/populate.html, if I set a ref property to an object, and not an ID, when getting it, I should get back an object and not an ID. I'm referring to this part of the page:
var guille = new Person({ name: 'Guillermo' });
guille.save(function (err) {
if (err) return handleError(err);
story._creator = guille;
console.log(story._creator.name);
// prints "Guillermo" in mongoose >= 3.6
// see https://github.com/LearnBoost/mongoose/wiki/3.6-release-notes
Here's my sample code:
var T1schema = new mongoose.Schema({
otherModel:{type:mongoose.Schema.Types.ObjectId, ref:"T2"}
});
var T1 = mongoose.model('T1', T1schema);
var T2schema = new mongoose.Schema({
email: {type: String},
});
var T2 = mongoose.model('T2', T2schema);
var t1 = new T1();
var t2 = new T2({email:"foo#bar.com"});
t1.otherModel = t2;
Now when I refer to t1.otherModel, it's just an ObjectId, and not a T2. For example:
console.log(t1.otherModel.email);
prints undefined instead of "foo#bar.com". Any ideas why? Note I'm using Mongoose 3.6.18 according to it's package.json.
Thanks!
I think your expectations here just don't match what mongoose does. The schema is a way of saying "model M's property P will always be of type T". So when you set a value, mongoose uses the schema definitions to cast the set value to the type the schema requires. Here's a little REPL session. Note setting a number property with a string value casts it to a number, but trying to store a boolean in a number field just ignores the errant value.
> var mongoose = require('mongoose')
> var schema = new mongoose.Schema({prop1: Number})
> var Model = mongoose.model('Model', schema)
> var m = new Model
> m.prop1 = 42
42
> m.prop1
42
> m.prop1 = "42"
'42'
> m.prop1
42
> m.prop1 = false
false
> m.prop1
42
So when your schema says something is going to be an ObjectId, if you give it a model instance, mongoose immediately converts it to an ObjectId in preparation for a write to the database, which is the common case. Normally if you just set that model instance, you don't need to get it back out of the parent model before saving the parent model to the database.
So the model instance getter defined properties are always going to return something compatible with the schema, and populate has to do with loading refs from the DB, but for whatever reason mongoose just doesn't work the same comparing a .populated instance with a non-populated instance. I can see why this is confusing and perhaps unexpected/disappointing though.
Mongoose is normalizing the instance to match the Schema, which specifies that otherModel is an ObjectId.
otherModel:{type:mongoose.Schema.Types.ObjectId, ref:"T2"}
So, Mongoose treats t1.otherModel = t2; the same as:
t1.otherModel = t2._id;
The ref isn't used until .populate() is called (either directly on the document or in a query), which needs both objects to be saved:
t2.save(function (err) {
t1.save(function (err) {
console.log(t1.otherModel);
// 7890ABCD...
t1.populate('otherModel', function () {
console.log(t1.otherModel);
// { email: 'foo#bar.com', _id: 7890ABCD..., __v: 0 }
});
});
});

Resources