How to add GeoJson data with mongoose? - node.js

I am sending the object to create a user model.
"{
type: 'Point',
coordinates: [ 25.2239771, 51.4993224 ]
}"
And, here is the Mongoose Schema that I created.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserProfileSchema = new Schema(
{
userId: {
type: String,
// required: true,
unique: true,
},
userFirstName: {
type: String,
// required: true,
},
userLastName: {
type: String,
// required: true,
},
userGender: {
type: String,
// required: true,
},
userCoordinates: {
type: {
type: String,
default: 'Point',
},
coordinates: {
type: [Number],
index: '2dsphere',
},
},
},
{ collection: 'userprofilemodels' }
);
module.exports = UserProfile = mongoose.model(
'userprofilemodels',
UserProfileSchema
);
This is the code that I am using to add geoJson type file. However, I am getting an error.
I also tried to add index after the Schema has been defined
await new userProfileModel({
userId,
userFirstName,
userLastName,
userCoordinates,
})
.save()
.then(() => {
console.log('it worked!');
res.send('worked!');
})
.catch((error) => {
console.log('did not worl')
// console.log(error);
});
If I exclude userCoordinates, then it works. So, def my geoJson object is wrong. However, I have no clue where I have made mistakes.

Mongoose supports GeoJSON objects indexing so first add the "2dsphere" index to the userCoordintes rather than to the coordinates within the object in order to make it work.
userCoordinates: {
type: {
type: String,
default: 'Point',
},
coordinates: {
type: [Number],
default: undefined,
required: true
},
index: '2dsphere'
},
Make sure your userCoordinates looks something like this:
const userCoordinates = {
type: "Point",
coordinates: [coordinatesA, coordinatesB],
};

Taken from the mongoose documentation it seems the GeoJSON Type mustn't be only a String.
here is the example with location as a GeoJSON type:
const citySchema = new mongoose.Schema({
name: String,
location: {
type: {
type: String, // Don't do `{ location: { type: String } }`
enum: ['Point'], // 'location.type' must be 'Point'
required: true
},
coordinates: {
type: [Number],
required: true
}
}
});

Related

How to receive information from a model inside an array in another model? (mongoose)

I have a "cart" model, and within my "order" model, I would like to have an array that receives the information sent by "cart" stored in an array. How can I do this through ref?
const mongoose = require('mongoose');
const CartSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
note: {
type: String,
required: true,
},
price: {
type: Number,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Cart", CartSchema);
order
const mongoose = require('mongoose');
const OrderSchema = new mongoose.Schema(
{
list: {
name: String,
notes: String,
},
totalAmount: {
type: Number,
required: true,
},
payment: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
addressNote: {
type: String,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Order", OrderSchema);
Here in "list" I would like it to be an array that receives cart model information
Can I do this through ref? What would be the best possible way?

How to receive an array from a model inside another model? (mongoose) (mongoDB)

I have an order model/schema, and my goal is that in this model in "list", I receive the information from the model cart in array format. How could I do this using ref?
cart model
const mongoose = require('mongoose');
const CartSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
note: {
type: String,
required: true,
},
price: {
type: Number,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Cart", CartSchema);
order
const mongoose = require('mongoose');
const OrderSchema = new mongoose.Schema(
{
list: {
name: String,
notes: String,
},
totalAmount: {
type: Number,
required: true,
},
payment: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
addressNote: {
type: String,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Order", OrderSchema);
Basically receive in array format the information of the model cart in "list" in model order
You should define your list as an array of ObjectIds referring to the Cart model:
const OrderSchema = new mongoose.Schema(
{
list: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Cart'
}],
...
});
Then, to retrieve the values in list, just populate the Order:
Order.find({}).populate('list').exec();

Mongoose Geolocation set default coordinates

I am trying to create mongoose geolocation records with default coordinates. I am able to set the default values so it they are serialized, but they are not really committed to the database so geospatial queries won't work. Here is what I am doing (simplified)
const Place = new mongoose.Schema({
name: { type: String, required: true },
location: {
type: {
type: String,
enum: ['Point'],
required: true,
default: 'Point'
},
coordinates: {
type: [Number],
required: true,
default: function () {
return [0, 0] // Just 0, 0 for the example
}
}
}
When I pull up the record in the mongo shell, there is no location key at all.
i don't know more efficient way
but try this :
//pass data like this in your controller
Store.create({name, lat, lon})
make your model like this
const Place = new mongoose.Schema({
name: { type: String, required: true },
lat: { type: String},
lon: { type: String},
location: {
type: {
type: String,
enum: ['Point'],
},
coordinates: {
type: [Number],
index: '2dsphere'
}
}
// run before saving documents
Place.pre('save', function(next) {
this.location = {
type: 'Point',
coordinates: [this.lat, this.lon]
};
next();
});

Node JS and Mongoose How to get data from 2 collections?

I need to get all docs from service collection and it's showing all records when i console content. In content collection there is field mids which is media id and all images are going to media collection. I need to get media url for specific service. But when i console content.mids it returns undefined .Do i need to change in query?
Code is attached for your reference.
// Controller
services: (req, res) => {
Posts.find({content_type:'service'}).then(function(content) {
console.log(content); //right
console.log(content.m_ids); //showing undefined
Media.findById(content.m_ids).then(media => {
res.render('default/services', {content: content, reqUrl: req.url});
});
})
}
Services Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Schema = new Schema({
content_type: {
type: String,
required: true,
maxlength:20
},
content_title: {
type: String,
required: true,
max:100
},
content_url: {
type: String,
required: true,
maxlength:200
},
content_description: {
type: String,
required: true,
},
content_full_description: {
type: String,
required: false,
},
pt_ids: {
type: String,
required: false,
},
pc_ids: {
type: String,
required: false,
},
m_ids: {
type: String,
required: false,
},
created_by_user_id: {
type: String,
default: 1,
},
created_on: {
type: Date,
default: Date.now
},
updated_on: {
type: Date,
default: Date.now
},
post_icon_svg: {
type: String,
required: false,
}
});
module.exports = {Posts: mongoose.model('content_data', PostsSchema )};
// Media Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MediaSchema = new Schema({
media_name: {
type: String,
required: true
},
media_title: {
type: String,
required: true
},
media_alt: {
type: String,
required: true
},
media_description: {
type: String,
required: false
},
media_url: {
type: String,
required: true,
unique: true
},
created_by_user_id: {
type: String,
default: 1,
},
created_on: {
type: Date,
default: Date.now
},
updated_on: {
type: Date,
default: Date.now
}
});
module.exports = {Media: mongoose.model('media', MediaSchema )};

geo element must be an array or object: type: "Point"

When I tried post request like this
"{ "imgUrl": "Server\Pictures\i14182109167", "text": "Myself in
seoul", "tag": ["seoul", "tour"], "geometry" : {"type": "Point","coordinates": [80,
-27]} }"
The error causes
'Can\'t extract geo keys: { _id:
ObjectId(\'5b8e204455526366f86a6383\'), tag: [ "seoul", "tour" ],
date: new Date(1536041028423), imgUrl:
"Server\Pictures\i14182109167", text: "Myself in seoul", geometry: {
type: "Point", coordinates: [ 80, -27 ], _id:
ObjectId(\'5b8e204455526366f86a6384\') }, __v: 0 } geo element must
be an array or object: type: "Point"' }
even I added "type": "Point" in post request but, why?
const geoSchema = new Schema({
type: {
type: String,
default: 'Point',
index: '2dsphere'
},
coordinates: {
type: [Number]
}
});
const memoSchema = new Schema({
imgUrl: {
type: String
},
text: {
type: String
},
date: {
type: Date,
default: Date.now
},
tag: {
type: [String]
},
user: {
type: Schema.Types.ObjectId,
ref: 'Memo'
},
geometry: geoSchema
})
I experienced this error, tried several schema declarations, until I fixed by this implementing this design:
1. Create a new schema, which has Point as a property.
const mongoose = require('mongoose');
const {Point} = require('mongoose-geojson-schema');
const pointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true
}
});
2. Schema for the object including above as a property:
const itemsSchema = new mongoose.Schema({
description: {
type: String,
required: true
},
location: {
type: pointSchema,
required: true
}
)
const Item = mongoose.model('Item', ItemsSchema);
module.exports = Item;
enter code here
3. Finally, my controller succesfully instantiates the object like this:
var geolocation =
{
type: 'Point',
coordinates: [
lng,
lat
]
};
const item = new Item({
description: req.body.description,
location: geolocation
})
Hope that helps.
I changed geometry to loc it worked!
but, I don't know why...
I was facing the same issue even after doing everything mention here. After spending too much time on this problem I get to know that if we save a default value it will work correctly.
Just follow the above answer and add
location: {
type: pointSchema,
default: {
type: 'Point',
coordinates: [0, 0],
},
required: false,
},
And delete the previous documents if any document has location.

Resources