Я пытаюсь вставить $push пару координат в документ, содержащий GeoJSON MultiLineString, вложенный следующим образом: [[[Number]]]
Когда я нахожу OneAndUpdate так:
req.body.point = [-123,347, 48,43649]
Route.findOneAndUpdate({name: req.body.name},
{'$push': { "route.coordinates.0": req.body.point}}, {new: true})
.then(doc => {
return res.send(doc)
}).catch(err => {
res.send(err)
})
Я получаю сообщение об ошибке:
errmsg": "Can't extract geo keys: { _id: ObjectId('5be9eef393311d2d2c6130fd').......
Point must only contain numeric elements",
"code": 16755,
Мои координаты действительны в формате [long, lat], как и ожидает монго. есть что-то, что мне здесь не хватает?
Это моя схема MultiLineString:
const MultiLineStringSchema = new Schema({
type: {
type: String,
enum: ['MultiLineString'],
required: true,
default: 'MultiLineString'
},
coordinates: {
type: [[[Number]]],
required: true
}
});
Это моя схема маршрута:
var { MultiLineStringSchema } = require('./GeoJson-Schemas')
const RouteSchema = new mongoose.Schema({
name: String,
route: {
type: MultiLineStringSchema,
required: true
}
});
RouteSchema.index({ route: "2dsphere" });
РЕДАКТИРОВАТЬ 2: здесь сохранен документ маршрута, в котором сохраняется ошибка. Я воссоздал ошибку с этим документом и обновил соответствующий _id в сообщении об ошибке выше.
{
"_id": {
"$oid": "5be9eef393311d2d2c6130fd"
},
"name": "A Route",
"route": {
"type": "MultiLineString",
"coordinates": [
[
[
-123.3867645,
48.4813423
],
[
-123.3785248,
48.4592626
],
[
-123.3766365,
48.4527165
],
[
-123.3756924,
48.4523749
],
[
-123.3722591,
48.4549366
],
[
-123.3704567,
48.4559612
]
]
],
"_id": {
"$oid": "5be9eef393311d2d2c6130fe"
}
},
"__v": 0
}
Продвинувшись на один шаг вперед, я добавил параметр {_id: false} в поддокумент MultiLineString и повторно инициализировал новую коллекцию. При сохранении нового документа следующим образом:
{
"_id": "5be9f076e1caaa23682d80de",
"name": "A Route",
"route": {
"type": "MultiLineString",
"coordinates": [
[
[
-123.3867645,
48.4813423
],
[
-123.3785248,
48.4592626
],
[
-123.3766365,
48.4527165
],
[
-123.3756924,
48.4523749
],
[
-123.3722591,
48.4549366
],
[
-123.3704567,
48.4559612
]
]
]
},
"__v": 0
}
Я пытаюсь найтиOneAndUpdate с точным синтаксисом:
Route.findOneAndUpdate({name},
{'$push': { "route.coordinates.0": point}}, {new: true})
.then(doc => {
return res.send(doc)
}).catch(err => {
res.send(err)
})
И получаю ту же ошибку:
"errmsg": "Can't extract geo keys: { _id: ObjectId('5be9f076e1caaa23682d80de')...
Point must only contain numeric elements",
"code": 16755,
ИЗМЕНИТЬ 3:
Двигаясь вперед еще раз, я обновил RouteSchema, удалив поддокумент полностью, чтобы он выглядел следующим образом:
const RouteSchema = new mongoose.Schema({
name: String,
route: {
type: {
type: String,
enum: ['MultiLineString'],
required: true,
default: 'MultiLineString'
},
coordinates: {
type: [[[Number]]],
required: true
}
}
});
Я храню документ так:
{
"_id": {
"$oid": "5be9f3915fc64e3548603766"
},
"route": {
"type": "MultiLineString",
"coordinates": [
[
[
-123.3867645,
48.4813423
],
[
-123.3785248,
48.4592626
],
[
-123.3766365,
48.4527165
],
[
-123.3756924,
48.4523749
],
[
-123.3722591,
48.4549366
],
[
-123.3704567,
48.4559612
]
]
]
},
"name": "A Route",
"__v": 0
}
и FindOneAndUpdate снова с точным синтаксисом и получают ту же ошибку.
Route.findOneAndUpdate({name},
{'$push': { "route.coordinates.0": point}}, {new: true})
.then(doc => {
return res.send(doc)
}).catch(err => {
res.send(err)
})
"errmsg": "Can't extract geo keys: { _id: ObjectId('5be9f3915fc64e3548603766')
Point must only contain numeric elements",
"code": 16755,
ИЗМЕНИТЬ 4:
mLab размещает экземпляр Mongo версии 3.6.6 индексирует коллекцию Route ФОТО а>
Запуск соединения оболочки db.routes.getIndexes() ON обеспечивает следующее.
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "testbench.routes"
},
{
"v" : 2,
"key" : {
"route" : "2dsphere"
},
"name" : "route_2dsphere",
"ns" : "testbench.routes",
"background" : true,
"2dsphereIndexVersion" : 3
}
]
_id
, указанному в ошибке.ObjectId('5be90afce2b53a23e0f83bda')
. Сообщение об ошибке предполагает, что данные не хранятся так, как вы ожидаете. Также"Point"
в сообщении об ошибке, похоже, также подтверждает это. - person Neil Lunn   schedule 12.11.2018RouteSchema
, параметр координат - это вложенный массив, в который я пытаюсь$push
войти. спасибо любезно. - person Bdyce   schedule 12.11.2018rrmsg": "Can't extract geo keys: { _id: ObjectId('5be90afce2b53a23e0f83bda')
Поэтому я прошу вас показать тот документ, идентифицированный данным значением_id
. Либо показывая этот документ, либо полное сообщение об ошибке, потому что проблема именно в этом. Почти так же, как и с недопустимой структурой GeoJSON. - person Neil Lunn   schedule 12.11.2018{ route: { type, coordinates, _id } }
, поскольку вы определилиSchema
для вложенного документа, в который он автоматически включил_id
, что также недопустимо. Вы должны включить{ _id: false }
в параметры определения схемы или просто встроить определения полей, так как это не то, для чего на самом деле предназначены отдельные определения схемы. Это может быть реальной проблемой здесь, поскольку ошибка может относиться к_id
внутри поддокументаroute
, но предоставление всего документа, фактически соответствующего данной ошибке, проясняет ситуацию. . - person Neil Lunn   schedule 12.11.2018getIndexes()
в коллекции. . Ошибка, кажется, указывает на то, что вы сделали что-то действительно неправильное с индексом здесь. - person Neil Lunn   schedule 13.11.2018db.routes.getIndexes()
во время оболочки для экземпляра, спасибо за усилия. - person Bdyce   schedule 13.11.2018point
? На первый взгляд, я мог бы сказать, что вы пытаетесь добавить структуру GeoJSON Point в массив, и это разбивает индекс с сообщением. В основном у вас должно быть что-то, разрешающее{ "$push": { "route.coordinates.0": [ -123.3704568, 48.4559612 ] } }
, которое, конечно, добавляет новый элемент с индексом без ошибок. - person Neil Lunn   schedule 13.11.2018MultiLineString
может быть не тем, что вам действительно нужно здесь, и, возможно, было бы лучше хранитьPoint
в отдельных документах. Это зависит от того, что вы действительно собираетесь делать с данными, и вопрос не в описании этого намерения. В 9/10 случаях люди просто извлекают GeoJSON из внешнего источника и сохраняют его именно в том виде, в котором они его получили, и в большинстве этих случаев вам действительно лучше хранить отдельныеPoint
документы в коллекции с некоторой связанной информацией для группы. - person Neil Lunn   schedule 13.11.2018point
здесь более чем правдоподобная проблема. Поскольку вы используете mongoose, он творит чудеса, сравнивая операторupdate()
(и варианты) со схемой и выполняя приведение типов. Таким образом, даже если это выглядит как массив, такие вещи, как строки для элементов, могут быть неправильно приведены к типу. Вероятно, это артефакт нотацииcoordinates.0
, которая строго не сочетается со структурой вложенного массива, что приводит к тому, что преобразованиеNumber
не происходит. Кастинг вручную черезparseFloat
должен исправить это. - person Neil Lunn   schedule 13.11.2018point
в[-123.3701134, 48.4467389]
, где координаты относятся к длинному/широтному числу с плавающей запятой и являются точкой на сфере. Фактическая переменнаяpoint
в коде обновления разрешается в массив. Идея, лежащая в основе схемы MultiLineString поверх чего-то вроде схемы Point или LineString, состоит в том, чтобы иметь возможность протолкнуть новую часть маршрута в первый массив, что приведет к двумLineStrings
, чтобы маршрут мог закончиться и продолжиться где-то еще. - person Bdyce   schedule 13.11.2018req.body.point
, назначив массив переменной и используяparseFloat(coords[0])
иparseFloat(coords[1])
, а затем вручную загрузив значения в массив, который будет{'$push': { "route.coordinates.0": [long, lat]}}
помещен в массив, и все равно не повезло, то же самое ошибка сохраняется. - person Bdyce   schedule 13.11.2018