Подтвердить что ты не робот

Mongoose: CastError: Cast to ObjectId не удалось присвоить значение "[object Object]" по пути "_id"

Я новичок в node.js, поэтому я чувствую, что это будет что-то глупое, что я упустил, но я не смог найти ответ, который исправляет мою проблему. Я пытаюсь создать путь, который создаст новый дочерний объект, добавит его в родительский массив дочерних элементов, а затем вернет дочерний объект в запросчик. Проблема, с которой я сталкиваюсь, заключается в том, что если я передаю идентификатор строки в findById, node сработает с

TypeError: Object {} не имеет метода 'cast'

Если я попытаюсь передать ObjectId вместо этого, я получаю

CastError: Cast to ObjectId не удалось присвоить значение "[object Object]" в пути "_id"

Вот пример моего кода:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //Have also tried Schema.Types.ObjectId, mongoose.ObjectId

mongoose.connect('mongodb://user:[email protected]:port/database');

app.get('/myClass/:Id/childClass/create', function(request, result) {
  var id = new ObjectId(request.params.Id);
  MyClass.findById(id).exec( function(err, myClass) {
    if (err || !myClass) { result.send("error: " + err + "<br>" + JSON.stringify(id) || ("object '" + request.params.Id + "' not found: " + id)); return; }
    var child = ChildClass();
    myClass.Children.addToSet(child);
    myClass.save();
    result.send(child);
  });
});

Если я исполню этот код с помощью пути "/myClass/51c35e5ced18cb901d000001/childClass/create", это будет выход кода:

error: CastError: Cast to ObjectId не удалось присвоить значение "[Object Object]" по пути "_id" { "Путь": "51c35e5ced18cb901d000001", "экземпляр": "ObjectID", "валидаторы": [], "сеттеры": [], "геттеры": [], "_ Индекс": NULL}

Я попытался использовать findOne и перешел в {_id: id}, но это похоже на то, что делает findById. Я пробовал разные классы для ObjectId, которые я видел на других сайтах. Я попытался вызвать ObjectId() как функцию вместо конструктора и возвращает undefined. На данный момент у меня заканчиваются идеи, и не кажется, что поиск в поисковых системах помогает. Любые идеи о том, что я делаю неправильно?

Кроме того, как я уже сказал, я новичок в node/Mongo/Mongoose/Express, поэтому, если есть лучший способ выполнить мою цель, пожалуйста, дайте мне знать. Я ценю всю обратную связь.

EDIT:

После обходного пути от Питера Лиона я искал еще одну ошибку, с которой я столкнулся, и нашел findByIdAndUpdate, которая работает так, как ожидалось, и делает именно то, что я надеялся сделать. Я все еще не уверен, почему findById и findOne дают мне такие проблемы, и мне любопытно узнать (возможно, отчет об ошибке должен быть подан), поэтому я оставлю это открытым, если у кого-то есть ответ.

4b9b3361

Ответ 1

Короткий ответ: используйте mongoose.Types.ObjectId.

Mongoose (но не mongo) может принимать идентификаторы объектов как строки и "отливать" их правильно для вас, поэтому просто используйте:

MyClass.findById(req.params.id)

Однако оговорка заключается в том, что req.params.id не является допустимым форматом для строки идентификатора mongo, которая выдает исключение, которое вы должны уловить.

Таким образом, основная непонятная вещь для понимания заключается в том, что mongoose.SchemaTypes имеет материал, который вы используете только при определении схем мангуста, а mongoose.Types - материал, который вы используете при создании объектов данных, которые хотите сохранить в базе данных или объектах запроса. Таким образом, mongoose.Types.ObjectId("51bb793aca2ab77a3200000d") работает, даст вам объект, который вы можете хранить в базе данных или использовать в запросах, и будет генерировать исключение, если ему задана неверная строка идентификатора.

findOne принимает объект запроса и передает экземпляр одной модели в обратный вызов. И findById буквально является оберткой findOne({_id: id}) (здесь см. Исходный код). Просто find принимает объект запроса и передает обратный вызов массив совпадающих экземпляров модели.

Просто медленно. Это сбивает с толку, но я могу гарантировать, что вы сбиваетесь с толку и не нажимаете на ошибки в мангусте в этот момент. Это довольно зрелая библиотека, но требуется некоторое время, чтобы понять ее.

Другая подозрительная вещь, которую я вижу в вашем фрагменте, не использует new при создании экземпляра ChildClass. Кроме того, вам нужно будет опубликовать код схемы, чтобы мы могли помочь вам удалить любые оставшиеся CastErrors.

Ответ 2

Я сталкивался с этой ошибкой, потому что значение, которое вы хотите отфильтровать в поле _id, не в формате идентификатора, одно "если" должно решить эту проблему.

const mongoose = require('mongoose');

console.log(mongoose.Types.ObjectId.isValid('53cb6b9b4f4ddef1ad47f943'));
// true
console.log(mongoose.Types.ObjectId.isValid('whatever'));
// false

Чтобы решить эту проблему, всегда проверяйте, является ли значение критерия для поиска действительным ObjectId

const criteria = {};
criteria.$or = [];

if(params.q) {
  if(mongoose.Types.ObjectId.isValid(params.id)) {
    criteria.$or.push({ _id: params.q })
  }
  criteria.$or.push({ name: { $regex: params.q, $options: 'i' }})
  criteria.$or.push({ email: { $regex: params.q, $options: 'i' }})
  criteria.$or.push({ password: { $regex: params.q, $options: 'i' }})
}

return UserModule.find(criteria).exec(() => {
  // do stuff
})

Ответ 3

Для всех тех людей, которые застряли в этой проблеме, но все равно не смогли ее решить: я наткнулся на ту же ошибку и обнаружил, что поле _id пусто.

Я описал его здесь более подробно. Все еще не нашли решения, кроме изменения полей в тегах _id и not-ID, которые для меня являются грязными. Вероятно, я собираюсь подать отчет об ошибке для мангуста. Любая помощь будет оценена!

Изменить: я обновил свою тему. Я подал билет, и они подтвердили недостающую проблему _id. Он будет исправлен в версии 4.x.x, у которой есть доступ к релизу прямо сейчас. Rc не рекомендуется для продуктивного использования!

Ответ 4

Если у вас есть эта проблема, и вы выполняете заполнение где-то вдоль строк, см. эту проблему Mongoose.

Обновление до Mongoose 4.0 и проблема исправлена.

Ответ 5

Имел ту же проблему, я просто принудил идентификатор к строке.

Моя схема:

const product = new mongooseClient.Schema({
    retailerID: { type: mongoose.SchemaTypes.ObjectId, required: true, index: true }
});

И затем при вставке:

retailerID: `${retailer._id}`

Ответ 6

Я получал эту ошибку CastError: Cast to ObjectId не удалось присвоить значение "[Object Object]" по пути "_id" после создания схемы, затем изменил ее и не смог ее отслеживать. Я удалил все документы в коллекции, и я мог добавить 1 объект, но не второй. Я закончил удаление коллекции в Монго, и это сработало, поскольку Mongoose воссоздал коллекцию.

Ответ 7

Для записи: у меня была эта ошибка, пытающаяся неправильно заполнить поддоку:

{
[CastError: Cast to ObjectId failed for value "[object Object]" at path "_id"]
message: 'Cast to ObjectId failed for value "[object Object]" at path "_id"',
name: 'CastError',
type: 'ObjectId',
path: '_id'
value:
  [ { timestamp: '2014-07-03T00:23:45-04:00',
  date_start: '2014-07-03T00:23:45-04:00',
  date_end: '2014-07-03T00:23:45-04:00',
  operation: 'Deactivation' } ],
}

look ^ value - это массив, содержащий объект: wrong!

Объяснение: Я отправил данные из php в API node.js следующим образом:

$history = json_encode(
array(
  array(
  'timestamp'  => date('c', time()),
  'date_start' => date('c', time()),
  'date_end'   => date('c', time()),
  'operation'  => 'Deactivation'
)));

Как вы можете видеть, $history - это массив, содержащий массив. Поэтому mongoose пытается заполнить _id (или любое другое поле) массивом вместо Scheme.ObjectId(или любого другого типа данных). Следующие работы:

$history = json_encode(
array(
  'timestamp'  => date('c', time()),
  'date_start' => date('c', time()),
  'date_end'   => date('c', time()),
  'operation'  => 'Deactivation'
));

Ответ 8

У меня была та же проблема. Вывод из моего Node.js устарел. После обновления он работает.

Ответ 9

Я также столкнулся с этой ошибкой mongoose. CastError: Cast to ObjectId не удалось получить значение \ "583fe2c488cf652d4c6b45d1 \" по пути  \ "_ id \" для модели Пользователь

Итак, я запускаю команду списка npm для проверки версии mongodb и mongoose в моем локальном. Вот отчет: ......
......
├── [email protected]
├── [email protected]
.....

Кажется, есть проблема в этой версии mongodb, поэтому я деинсталлировал и пытаюсь использовать другую версию, такую ​​как 2.2.16

$ npm uninstall mongodb, он удалит mongodb из вашего каталога node_modules. После этого установите нижнюю версию mongodb.
$ npm install [email protected]
Наконец, я перезапущу приложение, и CastError ушел!

Ответ 10

просто измените путь, он будет работать, например,

app.get('/myClass/:Id/childClass/create', function(request, result) .....

изменить на

app.get('/myClass**es**/:Id/childClass/create', function(request, result) .....

Я просто добавил --es-- к пути (myClass), чтобы стать (myClasses)

теперь должно работать и не увидит ту ошибку