I'm trying to make a spatial query where in my database I have a collection with has area (a polygon) and i would like to find areas where cover this point.
Here is the GIST to test:
https://gist.github.com/mariohmol/0cfebdcbdd885bf71e6f79e629f8eb63
some parts of the code.
Schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var assert = require('assert')
console.log('\n===========');
console.log(' mongoose version: %s', mongoose.version);
console.log('========\n\n');
var dbname = 'testing_geojsonPoint';
mongoose.connect('localhost', dbname);
mongoose.connection.on('error', function () {
console.error('connection error', arguments);
});
var schema = new Schema({
loc: {
type: { type: String },
coordinates: []
},
area: {
type: { type: String, default: 'Polygon' },
coordinates: []
}
});
schema.index({ loc: '2dsphere' });
schema.index({ area: '2dsphere' });
var A = mongoose.model('A', schema);
I'm getting this error on mongoose version: 4.8.4:
//If I use this, works for the nearest
{ area: { $near: {
type: 'Point', coordinates: [-43.941932916641235,-19.931718548878326] }}}
//but if i do with geowithin it gives me the error:
{ area: {
$geoWithin: { $geometry: {
type: 'Point', coordinates: [-43.941932916641235,-19.931718548878326]
}}
Error: Invalid geoJSON type for $geoWithin "Point", must be "Polygon" or "MultiPolygon"
at cast (/node_modules/mongoose/lib/cast.js:159:25)
Related
I have 2 schema in mongoose as follows:
PointSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point']
},
coordinates: {
type: [Number]
},
index: {
type: '2dsphere',
sparse: true
}
});
module.exports = {
PointSchema
};
DeviceSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = require('./PointSchema').PointSchema;
const DeviceSchema = mongoose.Schema({
name: String,
location: {
type: PointSchema,
default: null
}
}, {
collection: 'devices',
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
});
module.exports = mongoose.model('Device', DeviceSchema);
Is there some problem in PointSchema.js as it is giving following error:
TypeError: Invalid schema configuration: 2dsphere is not a valid
type at path index.
Followed this documentation to create PointSchema.js: https://mongoosejs.com/docs/geojson.html
I solved my problem with the next configuration in the model!
module.exports = (mongoose) => {
const DomainSchema = new mongoose.Schema({
domain_id: { type: Number },
name: String,
domain_data: {
type: { type: String },
coordinates: { type: Array },
},
});
DomainSchema.index({ domain_data: '2dsphere' });
return mongoose.model('Domain', DomainSchema);
};
I am frustrated about mongodb geonear aggregate query, for each response i get error like this :
{"name":"MongoError","message":"geoNear command failed: { ok: 0.0, errmsg: \"error processing query: ns=Lab.assoprofiles limit=100Tree: GEONEAR field=loc maxdist=50000 isNearSphere=1\nSort: {}\nProj: { $pt: { $meta: \"geoNearPoin...\", code: 2, codeName: \"BadValue\" }","ok":0,"errmsg":"geoNear command failed: { ok: 0.0, errmsg: \"error processing query: ns=Lab.assoprofiles limit=100Tree: GEONEAR field=loc maxdist=50000 isNearSphere=1\nSort: {}\nProj: { $pt: { $meta: \"geoNearPoin...\", code: 2, codeName: \"BadValue\" }","code":16604,"codeName":"Location16604"}
This how i designed the collection :
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
var AssoSchema = new mongoose.Schema({
userId:{ type: mongoose.Schema.Types.ObjectId, ref: "User"},
picture : String,
telephone: {
type: String,
unique: false
},
loc: {
type: [Number], // [<longitude>, <latitude>]
index: "2d" // create the geospatial index
},
},{timestamps: true})
var Asso = mongoose.model('AssoProfile', AssoSchema);
module.exports = Asso;
And query is like this :
const latitude = parseFloat(req.body.latitude);
const longitude = parseFloat(req.body.longitude);
AssoProfile.aggregate([
{
$geoNear: {
near: { type: 'Point', coordinates: [latitude, longitude] },
spherical: true, distanceField: 'distance', maxDistance:7000,
}
}
], function(err, l ){
console.log(JSON.stringify(err));
console.log(l);
})
I don't understand why such simple query throws this error.
Thanks for your helps.
I have run same code you have posted above but It didn't work for me... And I think index: 2d is not an option in mongoose model. And instead I have created index like this and worked for me.
const mongoose = require("mongoose")
var Schema = mongoose.Schema
var AssoSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
picture : String,
telephone: {
type: String,
unique: false
},
loc: Array,
}, { timestamps: true })
AssoSchema.index({ 'loc': '2dsphere' })
var Asso = mongoose.model('AssoProfile', AssoSchema)
module.exports = Asso;
I'm getting the following error:
MongoError: Can't extract geo keys: { _id: ObjectId('5aba6a88d366dbbf6c83a5d3'), gpshits: [ { coordinates: [ 6.982654547382455, 46.88414220428685 ], _id: ObjectId('5aba6a8fd366dbbf6c83a5d4'), type: "Point" } ], licenseplate: "xxaa22", createdAt: new Date(1522166408205), updatedAt: new Date(1522166415372), __v: 0 } Point must only contain numeric elements
Is it because i'm incorrectly nesting my Point in the model? I've read the docs but i cant find an example how to properly target the array. It's not giving any errors. Mainly trying to keep a log of GPS hits on a vehicle license plate number.
Model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var VehicleSchema = new Schema({
licenseplate: {type: String, required: true, unique:true},
gpshits : [{
type: { type: String },
coordinates:[mongoose.Schema.Types.Mixed]
}]
},
{
timestamps: true
}
);
VehicleSchema.index({'gpshits' : '2dsphere'});
module.exports = mongoose.model('Vehicle', VehicleSchema);
Function:
function (req, res) {
Joi.validate(req.body, Schemas.gpshit)
.then(function () {
return Vehicle.update({
licenseplate: req.body.licenseplate
}, {
$push: {
'gpshits': req.body.hit
}
}).exec();
})
.then(function () {
return res.status(200).json({
success: true
});
})
.catch(function (err) {
console.log(err)
return res.status(err.statusCode).json(err);
});
}
POST body:
{
"licenseplate": "xxaa22",
"hit" : {
"type" : "Point",
"coordinates": [6.982654547382455, 46.88414220428685]
}
}
Use parseFloat where you Insert the lattitude and longitude in mongoDB
var vehicle = new vehicle({
"licenseplate": licenseNumber,
"loc": {
"type": "Point",
"coordinates": [parseFloat(lng), parseFloat(lat)]
}
});
vehicle.save();
I fixed this by separating the array object into it's own schema and properly setting the coordinates field to '2dsphere' using index().
I am not a totally new populate user but now I do not know what's wrong.
Here I need to populate my designerId which is type of ObjectId. Take a look at my route.
ordersAdminRouter.route('/customorder/add')
.post(function(req, res){
body = req.body;
console.log(body);
CustomOrders.create(body, function(err, saved){
if (err) throw err;
Designs.findByIdAndUpdate(saved.designId, {$set: {status: 'Order Sent'}}, {new: true}).exec()
.then(function(updated){
return CustomOrders.findById(saved._id).populate(saved.designId).exec();
})
.then(function(orders){
res.json(orders);
})
.then(undefined, function(err){
console.log(err);
})
});
});
saved._id is working because when I remove the populate, it returns the document that I need without the populated document of course.
Take a look at my schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var customOrderSchema = new Schema({
designId: { type: Schema.Types.ObjectId, ref: 'customDesigns' },
size: { type: String },
quantity: { type: Number },
totalPrice: { type: Number },
paymentMode: { type: String },
rcpt_img: { type: String },
refNumber: { type: String }
});
module.exports = mongoose.model('customOrders', customOrderSchema);
Here is my customDesigns schema.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var customDesignSchema = new Schema({
item_name: { type: String },
price: { type: Number, default: 0 },
img_url_front: { type: String },
img_url_back: { type: String },
designer: { type: Schema.Types.ObjectId, ref: 'users' },
color: { type: String },
designDate: { type: Date, default: Date.now() },
status: { type: String, default: 'For Qoutation' }
});
module.exports = mongoose.model('customDesigns', customDesignSchema);
I need to admit that I am new to promises on mongoose & express and this is my first time doing so. But using populate, i use it more than I can think of. Any suggestions?
return CustomOrders.findById(saved._id).populate('designId').then(.. your code);
By the way, you dont must use .exec() then you want execute your query, .then executes query as well. You can skip .exec()
http://mongoosejs.com/docs/populate.html
http://mongoosejs.com/docs/api.html#query_Query-populate
I am using mongoose for my mongodb.
I am trying to update the existing document with an array of data.
Here's my code:
exports.transactions = function(req,res)
{
var transactions = req.body.transactions;
transactions.forEach(function(transaction){
// console.log("hello "+transaction);
// });
console.log(req.body.user._id);
Dwolla.update({user_id: req.body.user._id}, {$push: {"transactions": {Amount: transaction.Amount, DestinationId: transaction.DestinationId, DestinationName: transaction.DestinationName, SourceId:transaction.SourceId,SourceName:transaction.SourceName,status:transaction.Status}}},
{ upsert: true},
function(err, model) {
if(err) console.log(err);
console.log("success");
}
);
});
}
The error i am getting when upsert is true is:
oldCb(error, result ? result.result : { ok: 0, n: 0, nModified: 0 });
TypeError: object is not a function
at Query.callback (E:\ndash-nodejs\node_modules\mongoose
)
at E:\ndash-nodejs\node_modules\kareem\index.js:177:19
at E:\ndash-nodejs\node_modules\kareem\index.js:109:16
at process._tickCallback (node.js:355:11)
Model:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var dwollaSchema = new Schema({
user_id:{ type: String},
username: { type: String },
dwolla_id: { type: String },
transactions: [{
Amount: String,
DestinationId:String,
DestinationName:String,
SourceId:String,
SourceName:String,
status:String
}],
modified: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Dwolla',dwollaSchema);