We had a geopoint (geo) field in our schema which was working with 6.x.x but after upagrading to 7.x.x it started giving errors
// model
import { getSchemaOptions } from '@common/utils/typegoose';
import { getModelForClass, index, prop as Property, Ref } from '@typegoose/typegoose';
import { ObjectId } from 'bson';
import { Field as GqlField, Float, ObjectType as GqlType } from 'type-graphql';
import { User } from '../user/user.model';
import { Address } from '../_common/embed/address/address.embed';
import { IBusiness } from './business.interface';
@GqlType()
@index({ geo: '2dsphere' })
export class Business implements IBusiness {
@GqlField(_type => String)
readonly _id: ObjectId;
@GqlField({ nullable: true })
@Property({ required: false })
name: string;
@GqlField(_type => User, { nullable: true })
@Property({ ref: 'User' })
members: Ref<User>[];
@GqlField(_type => Address, { nullable: true })
@Property({ required: false })
address: Address;
@GqlField(_type => [Float], { nullable: true })
@Property({ required: false })
public geo: [number];
}
export const BusinessModel = getModelForClass(Business, getSchemaOptions());
// stacktrace
{
"message": "Can't extract geo keys: { _id: ObjectId('5edcd899ac1dad3f2ad95828'), members: [ ObjectId('5edccbe2cfe386283ff0497f') ], name: \"Vaijapur business\", address: { _id: ObjectId('5edcd899ac1dad3f2ad95829') }, geo: [ [ 74.7436299 ], [ 19.915527 ] ], createdAt: new Date(1591531673898), updatedAt: new Date(1591531673898), __v: 0 } Point must only contain numeric elements",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"addBusiness"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"driver": true,
"name": "MongoError",
"index": 0,
"code": 16755,
"errmsg": "Can't extract geo keys: { _id: ObjectId('5edcd899ac1dad3f2ad95828'), members: [ ObjectId('5edccbe2cfe386283ff0497f') ], name: \"Vaijapur business\", address: { _id: ObjectId('5edcd899ac1dad3f2ad95829') }, geo: [ [ 74.7436299 ], [ 19.915527 ] ], createdAt: new Date(1591531673898), updatedAt: new Date(1591531673898), __v: 0 } Point must only contain numeric elements",
"stacktrace": [
"MongoError: Can't extract geo keys: { _id: ObjectId('5edcd899ac1dad3f2ad95828'), members: [ ObjectId('5edccbe2cfe386283ff0497f') ], name: \"Vaijapur business\", address: { _id: ObjectId('5edcd899ac1dad3f2ad95829') }, geo: [ [ 74.7436299 ], [ 19.915527 ] ], createdAt: new Date(1591531673898), updatedAt: new Date(1591531673898), __v: 0 } Point must only contain numeric elements",
" at Function.create (/home/akash/magicbill/server/node_modules/mongodb/lib/core/error.js:43:12)",
" at toError (/home/akash/magicbill/server/node_modules/mongodb/lib/utils.js:149:22)",
" at coll.s.topology.insert (/home/akash/magicbill/server/node_modules/mongodb/lib/operations/common_functions.js:265:39)",
" at /home/akash/magicbill/server/node_modules/mongodb/lib/core/connection/pool.js:404:18",
" at process._tickCallback (internal/process/next_tick.js:61:11)"
]
}
}
}
no
Just to confirm doesn't work with
@Property({ required: false, type: Array })
public geo: [[number]];
I can insert it with mongo CLI if I do
db.businesses.insert({geo: [74.7436299, 19.915527]})
But when I do it on the mongoose model for some reason it passes the object as
geo: [ [ 74.7436299 ], [ 19.915527 ] ],
@akash-rajput since ~7.2 mapProp & arrayProp merged into prop, but as it has always been for an array you need to define either items or type with the correct type, for your case it would be type: Number
PS: i dont know the structure of geo things, this example is for [10,11,12,13] and not for [[10],[11],[12],[13]]
update: if you need [[10,10],[11,11]] then do type: Number, dim: 2
I think your problem could be related to the version of the index being used: https://docs.mongodb.com/manual/core/2dsphere/
You seem to be using legacy geojson format (version 2), but the index is probably created as version 3.
What this means is that your data structure should look more like loc : { type: "Point", coordinates: [ -73.88, 40.78 ] }, as per the docs there.
If you want to use the legacy format, you may need to specify "2dsphereIndexVersion": 2 as an index option, which I think allowed plain arrays.
Edit: also, the recommendations by @hasezoey above are also valid, and I think the correct type is this:
@Property({ required: false, type: Number })
public geo: [number, number];
@hasezoey yes that's what it is. Geo JSON point takes an array [lng,lat]. But yes passing number for array field I didn't get it. For reference this solved my issue:
@Property({ required: false, type: Number })
public geo: [number];
Much appreciate weekend help thanks :smiley: Can be closed.
Most helpful comment
@akash-rajput since ~7.2
mapProp&arrayPropmerged intoprop, but as it has always been for an array you need to define eitheritemsortypewith the correct type, for your case it would betype: NumberPS: i dont know the structure of geo things, this example is for
[10,11,12,13]and not for[[10],[11],[12],[13]]update: if you need
[[10,10],[11,11]]then dotype: Number, dim: 2